Skip to content

Instantly share code, notes, and snippets.

@asm0dey
Created January 6, 2020 12:59
Show Gist options
  • Save asm0dey/5d6fd867c0d2f87c38f90b27a9ff81bb to your computer and use it in GitHub Desktop.
Save asm0dey/5d6fd867c0d2f87c38f90b27a9ff81bb to your computer and use it in GitHub Desktop.
<!DOCTYPE html><html lang="en-US"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta property="og:type" content="website"><meta name="twitter:card" content="summary"><style>.bespoke-marp-note,.bespoke-marp-osc,.bespoke-progress-parent{display:none;-webkit-transition:none;transition:none}@media screen{body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;color:inherit;cursor:pointer;font-size:inherit;opacity:.8;outline:none;padding:0;-webkit-transition:opacity .2s linear;transition:opacity .2s linear;-webkit-tap-highlight-color:transparent}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:disabled,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:disabled,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:disabled{cursor:not-allowed;opacity:.15!important}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover{opacity:1}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:active,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:active,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover:active{opacity:.6}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled),body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled),body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button:hover:not(:disabled){-webkit-transition:none;transition:none}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev],body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button.bespoke-marp-presenter-info-page-prev{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNNjggOTBMMjggNTBsNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;overflow:hidden;text-indent:100%;white-space:nowrap}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button.bespoke-marp-presenter-info-page-next{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNMzIgOTBsNDAtNDAtNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;overflow:hidden;text-indent:100%;white-space:nowrap}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen]{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCIgcng9IjUuNjciLz48cGF0aCBjbGFzcz0iYSIgZD0iTTQwIDcwSDIwVjUwbTIwIDBMMjAgNzBtNDAtNDBoMjB2MjBtLTIwIDBsMjAtMjAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;overflow:hidden;text-indent:100%;white-space:nowrap}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button.exit[data-bespoke-marp-osc=fullscreen],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button.exit[data-bespoke-marp-osc=fullscreen]{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCIgcng9IjUuNjciLz48cGF0aCBjbGFzcz0iYSIgZD0iTTIwIDUwaDIwdjIwbS0yMCAwbDIwLTIwbTQwIDBINjBWMzBtMjAgMEw2MCA1MCIvPjwvc3ZnPg==")}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=presenter],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=presenter]{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS13aWR0aDo1cHh9PC9zdHlsZT48L2RlZnM+PHBhdGggY2xhc3M9ImEiIGQ9Ik0yMCA2MGgtNWE1IDUgMCAwMS01LTVWMjBhNSA1IDAgMDE1LTVoNjBhNSA1IDAgMDE1IDV2NU0zMCA4NWg2MCIvPjxyZWN0IHg9IjMwIiB5PSIzNSIgd2lkdGg9IjYwIiBoZWlnaHQ9IjQwIiByeD0iNSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIi8+PHJlY3QgY2xhc3M9ImEiIHg9IjMwIiB5PSIzNSIgd2lkdGg9IjYwIiBoZWlnaHQ9IjQwIiByeD0iNSIvPjxwYXRoIGNsYXNzPSJhIiBkPSJNNDAgNTBoNDBNNDAgNjBoMzAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;overflow:hidden;text-indent:100%;white-space:nowrap}body,html{height:100%;margin:0}body{background:#000;overflow:hidden}svg.bespoke-marp-slide{opacity:0;pointer-events:none;z-index:-1}svg.bespoke-marp-slide.bespoke-marp-active{opacity:1;pointer-events:auto;z-index:0}svg.bespoke-marp-slide[data-bespoke-marp-load=hideable]{display:none}svg.bespoke-marp-slide[data-bespoke-marp-load=hideable].bespoke-marp-active{display:block}[data-bespoke-marp-fragment=inactive]{visibility:hidden}body[data-bespoke-view=""] .bespoke-marp-parent,body[data-bespoke-view=next] .bespoke-marp-parent{bottom:0;left:0;position:absolute;right:0;top:0}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc{background:rgba(0,0,0,.65);border-radius:7px;bottom:50px;color:#fff;display:block;font-family:Helvetica,Arial,sans-serif;font-size:16px;left:50%;line-height:0;opacity:1;padding:12px;position:absolute;touch-action:manipulation;-webkit-transform:translateX(-50%);transform:translateX(-50%);-webkit-transition:opacity .2s linear;transition:opacity .2s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1;will-change:transform}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>*,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>*{margin-left:6px}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>:first-child,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>:first-child{margin-left:0}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>span,body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>span{opacity:.8}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>span[data-bespoke-marp-osc=page],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>span[data-bespoke-marp-osc=page]{display:inline-block;min-width:140px;text-align:center}body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen],body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=presenter],body[data-bespoke-view=""] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=presenter],body[data-bespoke-view=next] .bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev]{height:32px;line-height:32px;width:32px}body[data-bespoke-view=""] .bespoke-marp-parent.bespoke-marp-inactive,body[data-bespoke-view=next] .bespoke-marp-parent.bespoke-marp-inactive{cursor:none}body[data-bespoke-view=""] .bespoke-marp-parent.bespoke-marp-inactive>.bespoke-marp-osc,body[data-bespoke-view=next] .bespoke-marp-parent.bespoke-marp-inactive>.bespoke-marp-osc{opacity:0;pointer-events:none}body[data-bespoke-view=""] svg.bespoke-marp-slide,body[data-bespoke-view=next] svg.bespoke-marp-slide{height:100%;left:0;position:absolute;top:0;width:100%}body[data-bespoke-view=""] .bespoke-progress-parent{background:#222;display:-webkit-box;display:flex;height:5px;width:100%}body[data-bespoke-view=""] .bespoke-progress-parent+.bespoke-marp-parent{top:5px}body[data-bespoke-view=""] .bespoke-progress-parent .bespoke-progress-bar{-webkit-box-flex:0;flex:0 0 0;background:#0288d1;-webkit-transition:-webkit-flex-basis .2s cubic-bezier(0,1,1,1);transition:-webkit-flex-basis .2s cubic-bezier(0,1,1,1);transition:flex-basis .2s cubic-bezier(0,1,1,1);transition:flex-basis .2s cubic-bezier(0,1,1,1),-webkit-flex-basis .2s cubic-bezier(0,1,1,1)}body[data-bespoke-view=next]{background:transparent}body[data-bespoke-view=presenter]{background:#161616}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container{height:100%;left:0;position:absolute;top:0;width:100%;display:grid;grid-template-columns:2fr 1fr;grid-template-rows:minmax(140px,1fr) 2fr 3em;grid-template-areas:"current next" "current note" "info note"}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-parent{grid-area:current;position:relative;overflow:hidden}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-parent svg.bespoke-marp-slide{height:calc(100% - 40px);left:20px;position:absolute;pointer-events:none;top:20px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:calc(100% - 40px)}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-parent svg.bespoke-marp-slide.bespoke-marp-active{-webkit-filter:drop-shadow(0 3px 10px rgba(0,0,0,.5));filter:drop-shadow(0 3px 10px rgba(0,0,0,.5))}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-next-container{background:#222;cursor:pointer;display:none;grid-area:next;overflow:hidden;position:relative}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-next-container.active{display:block}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-next-container iframe.bespoke-marp-presenter-next{background:transparent;border:0;display:block;-webkit-filter:drop-shadow(0 3px 10px rgba(0,0,0,.5));filter:drop-shadow(0 3px 10px rgba(0,0,0,.5));height:calc(100% - 40px);left:20px;position:absolute;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;top:20px;width:calc(100% - 40px)}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container{background:#222;color:#ddd;grid-area:note}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note{margin:20px;width:calc(100% - 40px);height:calc(100% - 40px);box-sizing:border-box;overflow:auto;padding-right:3px;white-space:pre-wrap;word-wrap:break-word;scrollbar-width:thin;scrollbar-color:hsla(0,0%,86.7%,.5) transparent}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note::-webkit-scrollbar{width:6px}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note::-webkit-scrollbar-track{background:transparent}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note::-webkit-scrollbar-thumb{background:hsla(0,0%,86.7%,.5);border-radius:6px}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note:empty{pointer-events:none}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note.active{display:block}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note p:first-child{margin-top:0}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-note-container .bespoke-marp-note p:last-child{margin-bottom:0}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container{-webkit-box-align:center;align-items:center;box-sizing:border-box;color:#ddd;display:-webkit-box;display:flex;flex-wrap:nowrap;grid-area:info;-webkit-box-pack:center;justify-content:center;padding:0 10px}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-page,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-time,body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-timer{display:block;box-sizing:border-box;padding:0 10px;white-space:nowrap;width:100%}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container button{height:1.5em;line-height:1.5em;width:1.5em}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-page{-webkit-box-ordinal-group:3;order:2;text-align:center}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-page .bespoke-marp-presenter-info-page-text{display:inline-block;min-width:120px;text-align:center}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-time{color:#999;-webkit-box-ordinal-group:2;order:1;text-align:left}body[data-bespoke-view=presenter] .bespoke-marp-presenter-container .bespoke-marp-presenter-info-container .bespoke-marp-presenter-info-timer{color:#999;-webkit-box-ordinal-group:4;order:3;text-align:right}}@media print{.bespoke-marp-presenter-info-container,.bespoke-marp-presenter-next-container,.bespoke-marp-presenter-note-container{display:none}}</style><style>@charset "UTF-8";@import url("https://fonts.googleapis.com/css?family=Lato:400,900|Roboto+Mono:400,700&display=swap");div#p>svg>foreignObject>section{width:1280px;height:720px;box-sizing:border-box;overflow:hidden;position:relative;scroll-snap-align:center center}div#p>svg>foreignObject>section:after{bottom:0;content:attr(data-marpit-pagination);padding:inherit;pointer-events:none;position:absolute;right:0}div#p>svg>foreignObject>section:not([data-marpit-pagination]):after{display:none}/* Normalization */div#p>svg>foreignObject>section h1{font-size:2em;margin:0.67em 0}div#p>svg>foreignObject>section video::-webkit-media-controls{will-change:transform}@page{size:1280px 720px;margin:0}@media print{body,html{background-color:#fff;margin:0;page-break-inside:avoid;break-inside:avoid-page}div#p>svg>foreignObject>section{page-break-before:always;break-before:page}div#p>svg>foreignObject>section,div#p>svg>foreignObject>section *{-webkit-print-color-adjust:exact!important;color-adjust:exact!important}div#p>svg[data-marpit-svg]{display:block;height:100vh;width:100vw}}div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{display:block;height:auto;width:100%}@supports (-ms-ime-align:auto){div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{position:static}}div#p>svg>foreignObject>section svg[data-marp-fitting=svg].__reflow__{content:""}@supports (-ms-ime-align:auto){div#p>svg>foreignObject>section svg[data-marp-fitting=svg].__reflow__{position:relative}}div#p>svg>foreignObject>section [data-marp-fitting-svg-content]{display:table;white-space:nowrap}div#p>svg>foreignObject>section [data-marp-fitting-svg-content-wrap]{white-space:pre}div#p>svg>foreignObject>section img[data-marp-twemoji]{background:transparent;height:1em;margin:0 .05em 0 .1em;vertical-align:-.1em;width:1em}
/*!
* Marp / Marpit Gaia theme.
*
* @theme gaia
* @author Yuki Hattori
*
* @auto-scaling true
* @size 4:3 960px 720px
*/div#p>svg>foreignObject>section .hljs{display:block;overflow-x:auto;padding:.5em;background:#000;color:#f8f8f8}div#p>svg>foreignObject>section .hljs-comment,div#p>svg>foreignObject>section .hljs-quote{color:#aeaeae;font-style:italic}div#p>svg>foreignObject>section .hljs-keyword,div#p>svg>foreignObject>section .hljs-selector-tag,div#p>svg>foreignObject>section .hljs-type{color:#e28964}div#p>svg>foreignObject>section .hljs-string{color:#65b042}div#p>svg>foreignObject>section .hljs-subst{color:#daefa3}div#p>svg>foreignObject>section .hljs-link,div#p>svg>foreignObject>section .hljs-regexp{color:#e9c062}div#p>svg>foreignObject>section .hljs-name,div#p>svg>foreignObject>section .hljs-section,div#p>svg>foreignObject>section .hljs-tag,div#p>svg>foreignObject>section .hljs-title{color:#89bdff}div#p>svg>foreignObject>section .hljs-class .hljs-title,div#p>svg>foreignObject>section .hljs-doctag{text-decoration:underline}div#p>svg>foreignObject>section .hljs-bullet,div#p>svg>foreignObject>section .hljs-number,div#p>svg>foreignObject>section .hljs-symbol{color:#3387cc}div#p>svg>foreignObject>section .hljs-params,div#p>svg>foreignObject>section .hljs-template-variable,div#p>svg>foreignObject>section .hljs-variable{color:#3e87e3}div#p>svg>foreignObject>section .hljs-attribute{color:#cda869}div#p>svg>foreignObject>section .hljs-meta{color:#8996a8}div#p>svg>foreignObject>section .hljs-formula{background-color:#0e2231;color:#f8f8f8;font-style:italic}div#p>svg>foreignObject>section .hljs-addition{background-color:#253b22;color:#f8f8f8}div#p>svg>foreignObject>section .hljs-deletion{background-color:#420e09;color:#f8f8f8}div#p>svg>foreignObject>section .hljs-selector-class{color:#9b703f}div#p>svg>foreignObject>section .hljs-selector-id{color:#8b98ab}div#p>svg>foreignObject>section .hljs-emphasis{font-style:italic}div#p>svg>foreignObject>section .hljs-strong{font-weight:700}div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{max-height:580px}div#p>svg>foreignObject>section h1,div#p>svg>foreignObject>section h2,div#p>svg>foreignObject>section h3,div#p>svg>foreignObject>section h4,div#p>svg>foreignObject>section h5,div#p>svg>foreignObject>section h6{margin:.5em 0 0}div#p>svg>foreignObject>section h1 strong,div#p>svg>foreignObject>section h2 strong,div#p>svg>foreignObject>section h3 strong,div#p>svg>foreignObject>section h4 strong,div#p>svg>foreignObject>section h5 strong,div#p>svg>foreignObject>section h6 strong{font-weight:inherit}div#p>svg>foreignObject>section h1{font-size:1.8em}div#p>svg>foreignObject>section h2{font-size:1.5em}div#p>svg>foreignObject>section h3{font-size:1.3em}div#p>svg>foreignObject>section h4{font-size:1.1em}div#p>svg>foreignObject>section h5{font-size:1em}div#p>svg>foreignObject>section h6{font-size:.9em}div#p>svg>foreignObject>section blockquote,div#p>svg>foreignObject>section p{margin:1em 0 0}div#p>svg>foreignObject>section ol>li,div#p>svg>foreignObject>section ul>li{margin:.3em 0 0}div#p>svg>foreignObject>section ol>li>p,div#p>svg>foreignObject>section ul>li>p{margin:.6em 0 0}div#p>svg>foreignObject>section code{display:inline-block;font-family:Roboto Mono,monospace;font-size:.8em;letter-spacing:0;margin:-.1em .15em;padding:.1em .2em;vertical-align:baseline}div#p>svg>foreignObject>section pre{display:block;margin:1em 0 0;min-height:1em;overflow:visible}div#p>svg>foreignObject>section pre code{box-sizing:border-box;margin:0;min-width:100%;padding:.5em;font-size:.7em}div#p>svg>foreignObject>section pre code svg[data-marp-fitting=svg]{max-height:calc(580px - 1em)}div#p>svg>foreignObject>section blockquote{margin:1em 0 0;padding:0 1em;position:relative}div#p>svg>foreignObject>section blockquote:after,div#p>svg>foreignObject>section blockquote:before{content:"“";display:block;font-family:Times New Roman,serif;font-weight:700;position:absolute}div#p>svg>foreignObject>section blockquote:before{top:0;left:0}div#p>svg>foreignObject>section blockquote:after{right:0;bottom:0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}div#p>svg>foreignObject>section blockquote>:first-child{margin-top:0}div#p>svg>foreignObject>section mark{background:transparent}div#p>svg>foreignObject>section table{border-spacing:0;border-collapse:collapse;margin:1em 0 0}div#p>svg>foreignObject>section table td,div#p>svg>foreignObject>section table th{padding:.2em .4em;border-width:1px;border-style:solid}div#p>svg>foreignObject>section{background-image:linear-gradient(135deg,hsla(0,0%,53.3%,0),hsla(0,0%,53.3%,.02) 50%,hsla(0,0%,100%,0) 0,hsla(0,0%,100%,.05));font-size:35px;font-family:Lato,Avenir Next,Avenir,Trebuchet MS,Segoe UI,sans-serif;height:720px;line-height:1.35;letter-spacing:1.25px;padding:70px;width:1280px;word-wrap:break-word;color:#455a64;background-color:#fff8e1}div#p>svg>foreignObject>section>:first-child,div#p>svg>foreignObject>section>header:first-child+*{margin-top:0}div#p>svg>foreignObject>section a,div#p>svg>foreignObject>section mark{color:#0288d1}div#p>svg>foreignObject>section code{background:#6a7a7d;color:#fff8e1}div#p>svg>foreignObject>section h1 strong,div#p>svg>foreignObject>section h2 strong,div#p>svg>foreignObject>section h3 strong,div#p>svg>foreignObject>section h4 strong,div#p>svg>foreignObject>section h5 strong,div#p>svg>foreignObject>section h6 strong{color:#0288d1}div#p>svg>foreignObject>section pre>code{background:#455a64}div#p>svg>foreignObject>section blockquote:after,div#p>svg>foreignObject>section blockquote:before,div#p>svg>foreignObject>section footer,div#p>svg>foreignObject>section header,div#p>svg>foreignObject>section section:after{color:#6a7a7d}div#p>svg>foreignObject>section table td,div#p>svg>foreignObject>section table th{border-color:#455a64}div#p>svg>foreignObject>section table thead th{background:#455a64;color:#fff8e1}div#p>svg>foreignObject>section table tbody>tr:nth-child(odd) td,div#p>svg>foreignObject>section table tbody>tr:nth-child(odd) th{background:rgba(69,90,100,.1)}div#p>svg>foreignObject>section.invert{color:#fff8e1;background-color:#455a64}div#p>svg>foreignObject>section.invert a,div#p>svg>foreignObject>section.invert mark{color:#81d4fa}div#p>svg>foreignObject>section.invert code{background:#dad8c8;color:#455a64}div#p>svg>foreignObject>section.invert h1 strong,div#p>svg>foreignObject>section.invert h2 strong,div#p>svg>foreignObject>section.invert h3 strong,div#p>svg>foreignObject>section.invert h4 strong,div#p>svg>foreignObject>section.invert h5 strong,div#p>svg>foreignObject>section.invert h6 strong{color:#81d4fa}div#p>svg>foreignObject>section.invert pre>code{background:#fff8e1}div#p>svg>foreignObject>section.invert blockquote:after,div#p>svg>foreignObject>section.invert blockquote:before,div#p>svg>foreignObject>section.invert footer,div#p>svg>foreignObject>section.invert header,div#p>svg>foreignObject>section.invert section:after{color:#dad8c8}div#p>svg>foreignObject>section.invert table td,div#p>svg>foreignObject>section.invert table th{border-color:#fff8e1}div#p>svg>foreignObject>section.invert table thead th{background:#fff8e1;color:#455a64}div#p>svg>foreignObject>section.invert table tbody>tr:nth-child(odd) td,div#p>svg>foreignObject>section.invert table tbody>tr:nth-child(odd) th{background:rgba(255,248,225,.1)}div#p>svg>foreignObject>section.gaia{color:#fff8e1;background-color:#0288d1}div#p>svg>foreignObject>section.gaia a,div#p>svg>foreignObject>section.gaia mark{color:#81d4fa}div#p>svg>foreignObject>section.gaia code{background:#cce2de;color:#0288d1}div#p>svg>foreignObject>section.gaia h1 strong,div#p>svg>foreignObject>section.gaia h2 strong,div#p>svg>foreignObject>section.gaia h3 strong,div#p>svg>foreignObject>section.gaia h4 strong,div#p>svg>foreignObject>section.gaia h5 strong,div#p>svg>foreignObject>section.gaia h6 strong{color:#81d4fa}div#p>svg>foreignObject>section.gaia pre>code{background:#fff8e1}div#p>svg>foreignObject>section.gaia blockquote:after,div#p>svg>foreignObject>section.gaia blockquote:before,div#p>svg>foreignObject>section.gaia footer,div#p>svg>foreignObject>section.gaia header,div#p>svg>foreignObject>section.gaia section:after{color:#cce2de}div#p>svg>foreignObject>section.gaia table td,div#p>svg>foreignObject>section.gaia table th{border-color:#fff8e1}div#p>svg>foreignObject>section.gaia table thead th{background:#fff8e1;color:#0288d1}div#p>svg>foreignObject>section.gaia table tbody>tr:nth-child(odd) td,div#p>svg>foreignObject>section.gaia table tbody>tr:nth-child(odd) th{background:rgba(255,248,225,.1)}div#p>svg>foreignObject>section.lead{display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;flex-wrap:nowrap;-webkit-box-pack:center;justify-content:center}div#p>svg>foreignObject>section.lead h1,div#p>svg>foreignObject>section.lead h2,div#p>svg>foreignObject>section.lead h3,div#p>svg>foreignObject>section.lead h4,div#p>svg>foreignObject>section.lead h5,div#p>svg>foreignObject>section.lead h6{text-align:center}div#p>svg>foreignObject>section.lead h1 svg[data-marp-fitting=svg],div#p>svg>foreignObject>section.lead h2 svg[data-marp-fitting=svg],div#p>svg>foreignObject>section.lead h3 svg[data-marp-fitting=svg],div#p>svg>foreignObject>section.lead h4 svg[data-marp-fitting=svg],div#p>svg>foreignObject>section.lead h5 svg[data-marp-fitting=svg],div#p>svg>foreignObject>section.lead h6 svg[data-marp-fitting=svg]{--preserve-aspect-ratio:xMidYMid meet}div#p>svg>foreignObject>section.lead p{text-align:center}div#p>svg>foreignObject>section.lead blockquote>h1,div#p>svg>foreignObject>section.lead blockquote>h2,div#p>svg>foreignObject>section.lead blockquote>h3,div#p>svg>foreignObject>section.lead blockquote>h4,div#p>svg>foreignObject>section.lead blockquote>h5,div#p>svg>foreignObject>section.lead blockquote>h6,div#p>svg>foreignObject>section.lead blockquote>p{text-align:left}div#p>svg>foreignObject>section.lead blockquote svg[data-marp-fitting=svg]:not([data-marp-fitting-math]){--preserve-aspect-ratio:xMinYMin meet}div#p>svg>foreignObject>section.lead ol>li>p,div#p>svg>foreignObject>section.lead ul>li>p{text-align:left}div#p>svg>foreignObject>section.lead table{margin-left:auto;margin-right:auto}div#p>svg>foreignObject>section:after,div#p>svg>foreignObject>section footer,div#p>svg>foreignObject>section header{box-sizing:border-box;font-size:66%;height:70px;line-height:50px;overflow:hidden;padding:10px 25px;position:absolute}div#p>svg>foreignObject>section header{top:0}div#p>svg>foreignObject>section footer,div#p>svg>foreignObject>section header{left:0;right:0}div#p>svg>foreignObject>section footer{bottom:0}div#p>svg>foreignObject>section:after{right:0;bottom:0;font-size:80%}div#p>svg>foreignObject>section footer{display:table}div#p>svg>foreignObject>section[data-marpit-scope-Jc7UiZUZ] img{position:absolute;height:80%;right:15px;bottom:0}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]{display:block!important;padding:0!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:before,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:before{display:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]{all:initial;display:flex;flex-direction:row;height:100%;overflow:hidden;width:100%}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction=vertical]{flex-direction:column}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split]>div[data-marpit-advanced-background-container]{width:var(--marpit-advanced-background-split,50%)}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split=right]>div[data-marpit-advanced-background-container]{margin-left:calc(100% - var(--marpit-advanced-background-split, 50%))}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure{all:initial;background-position:center;background-repeat:no-repeat;background-size:cover;flex:auto;margin:0}div#p>svg>foreignObject>section[data-marpit-advanced-background=content],div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo]{background:transparent!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo],div#p>svg[data-marpit-svg]>foreignObject[data-marpit-advanced-background=pseudo]{pointer-events:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background-split]{width:100%;height:100%}</style></head><body><div class="bespoke-marp-osc"><button data-bespoke-marp-osc="prev" tabindex="-1" title="Previous slide">Previous slide</button><span data-bespoke-marp-osc="page"></span><button data-bespoke-marp-osc="next" tabindex="-1" title="Next slide">Next slide</button><button data-bespoke-marp-osc="fullscreen" tabindex="-1" title="Toggle fullscreen (f)">Toggle fullscreen</button><button data-bespoke-marp-osc="presenter" tabindex="-1" title="Open presenter view (p)">Open presenter view</button></div><div id="p"><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="1" data-class="lead" data-background-image="linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%)" data-color="white" data-theme="gaia" class="lead" style="--class:lead;--background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);--color:white;--theme:gaia;color:white;background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);background-position:center;background-repeat:no-repeat;background-size:cover;">
<h1>Как Java-роботы видят Python</h1>
<p>Паша Финкельштейн, Lamoda</p>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-class="lead invert" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-background-image="linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%)" data-color="white" data-theme="gaia" class="lead invert" data-marpit-pagination="2" data-marpit-pagination-total="28" style="--class:lead invert;--paginate:true;--background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);--color:white;--theme:gaia;color:white;background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);background-position:center;background-repeat:no-repeat;background-size:cover;">
<h1>Кто я</h1>
<ul>
<li>13 лет в IT</li>
<li>11 лет в разработке
<ul>
<li>Почти всё время на JVM</li>
</ul>
</li>
<li>Полгода <img class="emoji" draggable="false" alt="😱" src="https://twemoji.maxcdn.com/2/svg/1f631.svg" data-marp-twemoji=""/> в Python</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" data-marpit-pagination="3" data-marpit-pagination-total="28" style="--paginate:true;--theme:gaia;" data-marpit-advanced-background="background"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://source.unsplash.com/XECZHb6NoFo&quot;);"></figure></div></section></foreignObject><foreignObject width="1280" height="720"><section id="3" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" data-marpit-pagination="3" data-marpit-pagination-total="28" style="--paginate:true;--theme:gaia;" data-marpit-advanced-background="content"><footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="3" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-class="lead invert" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-background-image="linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%)" data-color="white" data-theme="gaia" class="lead invert" data-marpit-pagination="4" data-marpit-pagination-total="28" style="--class:lead invert;--paginate:true;--background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);--color:white;--theme:gaia;color:white;background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);background-position:center;background-repeat:no-repeat;background-size:cover;">
<h1>Я <img class="emoji" draggable="false" alt="❤️" src="https://twemoji.maxcdn.com/2/svg/2764.svg" data-marp-twemoji=""/> Python</h1>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-class="lead invert" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-background-image="linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%)" data-color="white" data-theme="gaia" class="lead invert" data-marpit-pagination="5" data-marpit-pagination-total="28" style="--class:lead invert;--paginate:true;--background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);--color:white;--theme:gaia;color:white;background-image:linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);background-position:center;background-repeat:no-repeat;background-size:cover;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Python <img class="emoji" draggable="false" alt="🐍" src="https://twemoji.maxcdn.com/2/svg/1f40d.svg" data-marp-twemoji=""/><img class="emoji" draggable="false" alt="💗" src="https://twemoji.maxcdn.com/2/svg/1f497.svg" data-marp-twemoji=""/> меня</span></foreignObject></svg></h1>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="6" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="left"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;images/MVC.png&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="67%" height="720" x="33%"><section id="6" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="6" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="left">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Как всё устроено в Java</span></foreignObject></svg></h1>
<ul>
<li>Скучно</li>
<li>Все всё понимают</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="default" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="6" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" data-marpit-pagination="7" data-marpit-pagination-total="28" style="--paginate:true;--theme:gaia;--marpit-advanced-background-split:40%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;images/MVC2.png&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="60%" height="720"><section id="7" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" data-marpit-pagination="7" data-marpit-pagination-total="28" style="--paginate:true;--theme:gaia;--marpit-advanced-background-split:40%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
<h1>Сложная логика?</h1>
<ul>
<li>Всё ещё скучно</li>
<li>Слишком просто</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="7" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-fragments="1" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="8" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:40%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;images/MVC2.png&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="60%" height="720"><section id="8" data-marpit-fragments="1" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="8" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:40%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
<h1>Фичефлаги?</h1>
<ul>
<li data-marpit-fragment="1">Ну вы поняли</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="lead" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="8" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-scope-Jc7UiZUZ="" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="9" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:30%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="left"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;images/VM.png&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="70%" height="720" x="30%"><section id="9" data-marpit-scope-Jc7UiZUZ="" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="9" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:30%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="left">
<h1>Django</h1>
<ul>
<li>А где логика?</li>
</ul>
<p><img src="images/7VE.gif" alt="drop-shadow" style="filter:drop-shadow(0 5px 10px rgba(0,0,0,.4));" /></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="default" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="9" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="10" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;" data-marpit-advanced-background="background"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg?v=a010291124bf&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="1280" height="720"><section id="10" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="10" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;" data-marpit-advanced-background="content"><footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="lead" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="10" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="11" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;">
<p><img src="images/forms.png" alt="drop-shadow height:250px" style="height:250px;filter:drop-shadow(0 5px 10px rgba(0,0,0,.4));" /></p>
<p><img src="images/template.png" alt="drop-shadow height:250px" style="height:250px;filter:drop-shadow(0 5px 10px rgba(0,0,0,.4));" /></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="12" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="left"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://source.unsplash.com/71CjSSB83Wo&quot;);"></figure></div></section></foreignObject><foreignObject width="67%" height="720" x="33%"><section id="12" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="12" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="left">
<h1>Звонок другу!</h1>
<p><a href="https://phalt.github.io/django-api-domains/">https://phalt.github.io/django-api-domains/</a></p>
<pre><code class="language-python"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_book</span><span class="hljs-params">(*, id: uuid.UUID)</span> -&gt; Book:</span>
book = Book.objects.get(id=id)
author = AuthorInterface.get_author(id=book.author_id)
<span class="hljs-keyword">return</span> {
<span class="hljs-string">'name'</span>: book.name,
<span class="hljs-string">'author_name'</span>: author.name,
}
</span></span></foreignObject></svg></code></pre>
<p><a href="https://django-best-practices.readthedocs.io/en/latest/applications.html#make-em-fat">django-best-practices/Make'em Fat</a></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="default" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="12" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="13" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;" data-marpit-advanced-background="background"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://source.unsplash.com/r-enAOPw8Rs&quot;);"></figure></div></section></foreignObject><foreignObject width="1280" height="720"><section id="13" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="13" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;" data-marpit-advanced-background="content"><footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="default" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="13" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="14" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="left"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;images/VM2.png&quot;);background-size:contain;"></figure></div></section></foreignObject><foreignObject width="67%" height="720" x="33%"><section id="14" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="14" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="left">
<h1>Где логика, Джанго?</h1>
<p><img src="https://vignette.wikia.nocookie.net/djangounchained/images/a/a4/Django.jpg/revision/latest?cb=20120601224011" alt="height:400px drop-shadow" style="height:400px;filter:drop-shadow(0 5px 10px rgba(0,0,0,.4));" /></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="lead" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="14" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="15" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Серьёзные ребята знают как делать правильно!</span></foreignObject></svg></h1>
<p><a href="https://github.com/mdn/kuma/blob/master/kuma/authkeys/models.py">github.com/mdn/kuma/blob/master/kuma/authkeys/models.py</a></p>
<pre><code class="language-python"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-keyword">from</span> django.utils.translation <span class="hljs-keyword">import</span> ugettext_lazy <span class="hljs-keyword">as</span> _
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_key</span><span class="hljs-params">()</span>:</span>
<span class="hljs-string">"""Generate a random API key."""</span>
...
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="16" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h2>Продолжаем разбирать</h2>
<pre><code class="language-python"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Key</span><span class="hljs-params">(models.Model)</span>:</span>
<span class="hljs-string">"""Authentication key"""</span>
...
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_secret</span><span class="hljs-params">(self)</span>:</span>
self.key = generate_key()
secret = generate_key()
self.hashed_secret = hash_secret(secret)
<span class="hljs-keyword">return</span> secret
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-marpit-fragments="4" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="17" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>А что не так-то?</h1>
<ul>
<li data-marpit-fragment="1">А что если нам понадобится поменять алгоритм шифрования?</li>
<li data-marpit-fragment="2">Логгирование прямо в модели?</li>
<li data-marpit-fragment="3">Сложную логику создать невозможно</li>
<li data-marpit-fragment="4">Транзакциями управлять тоже невозможно</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="18" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>В Spring</h1>
<pre><code class="language-java"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment">// View</span>
<span class="hljs-meta">@Controller</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyController</span> </span>{
<span class="hljs-meta">@Inject</span> MyService service;
<span class="hljs-meta">@GetRequest</span>(<span class="hljs-string">"/deal"</span>) <span class="hljs-function">UUID <span class="hljs-title">deal</span><span class="hljs-params">(@Valid Deal deal)</span></span>{
service.saveDeal(deal);
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="19" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>В Spring</h1>
<pre><code class="language-java"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment">// Controller</span>
<span class="hljs-meta">@Transactional</span>
<span class="hljs-meta">@Service</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyService</span> </span>{
<span class="hljs-meta">@Inject</span> Repo1 repo1; <span class="hljs-meta">@Inject</span> Repo2 repo2;
<span class="hljs-meta">@Inject</span> Repo3 repo3; <span class="hljs-meta">@Inject</span> Repo4 repo4;
<span class="hljs-function">Result&lt;UUID&gt; <span class="hljs-title">deal</span><span class="hljs-params">(Deal deal)</span></span>{
<span class="hljs-keyword">if</span>(<span class="hljs-comment">/* check */</span>) {}
<span class="hljs-keyword">else</span>(<span class="hljs-comment">/* check */</span>) {
repo1.save(<span class="hljs-comment">/* */</span>);
repo2.save(<span class="hljs-comment">/* */</span>);
}
<span class="hljs-keyword">return</span> <span class="hljs-comment">/**/;
</span></span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="20" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>В Spring</h1>
<pre><code class="language-java"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment">// Model</span>
<span class="hljs-meta">@Repository</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyService</span> </span>{
<span class="hljs-meta">@Inject</span> Datasource ds;
<span class="hljs-function">UUID <span class="hljs-title">save</span><span class="hljs-params">(Deal deal)</span></span>{
<span class="hljs-keyword">try</span>(<span class="hljs-keyword">var</span> con = ds.getConnection()){
<span class="hljs-keyword">var</span> stmt = con.createStatement(<span class="hljs-string">"INSERT INTO … RETURNING"</span>);
stmt.fetchResult();
<span class="hljs-keyword">return</span> <span class="hljs-comment">/* */</span>;
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="21" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>На что обратить внимание</h1>
<ul>
<li>DI</li>
<li>Разделение ответственности</li>
<li><code>Result&lt;UUID&gt;</code></li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="22" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>Если вы уже <img class="emoji" draggable="false" alt="😍" src="https://twemoji.maxcdn.com/2/svg/1f60d.svg" data-marp-twemoji=""/> DI</h1>
<p><a href="https://github.com/dry-python/dependencies">dry-python/dependencies</a></p>
<pre><code class="language-python"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyController</span><span class="hljs-params">(Injector)</span>:</span>
my_service = MyService
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyService</span><span class="hljs-params">(Injector)</span>:</span>
repo1 = Repo1
repo2 = Repo2
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Repo1</span><span class="hljs-params">(Injector)</span>:</span>
data_source = DataSource
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="23" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;">
<h1>Если вы уже <img class="emoji" draggable="false" alt="😍" src="https://twemoji.maxcdn.com/2/svg/1f60d.svg" data-marp-twemoji=""/> <code>Result&lt;UUID&gt;</code></h1>
<p><a href="https://github.com/dry-python/returns">dry-python/returns</a></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="24" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Сложно управлять транзакциями?</span></foreignObject></svg></h1>
<p><img src="https://www.plantuml.com/plantuml/svg/ZPBFIiD04CRl-nJZ0uZOzjI35Znw43nuBtGFXRMHDEBL9AANKfz1V84WMHjRNLzXvetyTi6aVuWra0spC_ERcMyoc2R3EBczDafTZVKT7PxGMJH9uiWO7VU9NxXaoojUSg4QntQOP5pnDqakJrn82lCB5yWXIMj0fOOc8Nc0Pu6BIXxPASApoRtKDz5ngEmGLuANoOnu9VD0-WWf8MYxY_6e1TVPmJLjILu3E_y2UfdwT76kj9bgahdSxnccY-glwu5G9UTtjiJMQxNH3XUdTJ_TdMsW_ID8QoKBGK7FjTGQ6BnjhNi0v9pnGfu9o_ZqF2-n1wVWkE35ju4xNXAE4Z6Etp29zMcmO1-4QbwDbh9-bjx-5VoEtMjPmn-h20rCHig_Qe0JF_GF" alt="drop-shadow height:480px" style="height:480px;filter:drop-shadow(0 5px 10px rgba(0,0,0,.4));" /></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-marpit-fragments="4" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="25" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<h1>Но не будем о грустном</h1>
<h3>Поговорим об исключениях</h3>
<ul>
<li data-marpit-fragment="1">
<p>Или это тоже грустное?</p>
</li>
<li data-marpit-fragment="2">
<p>В Python все исключения unchecked: хрен поймаешь.</p>
</li>
<li data-marpit-fragment="3">
<p>В Java можно поделить</p>
<ul>
<li data-marpit-fragment="4">Но множество «важных» исключений — checked: хрен откажешься ловить</li>
</ul>
</li>
</ul>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-class="default" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="default" data-marpit-pagination="26" data-marpit-pagination-total="28" style="--class:default;--paginate:true;--theme:gaia;">
<p>И что?</p>
<pre><code class="language-java"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">someFun</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">try</span> {
instance.call(payload);
} <span class="hljs-keyword">catch</span> (IOException e){
logger.info(<span class="hljs-string">"Can't write to FS"</span>);
} <span class="hljs-keyword">catch</span> (UnknownUserException e){
logger.info(<span class="hljs-string">"Who am I?"</span>)
}
<span class="hljs-comment">// etc, etc…</span>
}
</span></span></foreignObject></svg></code></pre>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="27" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="background" data-marpit-advanced-background-split="left"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://source.unsplash.com/YRgPxwbvY0E&quot;);"></figure></div></section></foreignObject><foreignObject width="67%" height="720" x="33%"><section id="27" data-class="lead" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead" data-marpit-pagination="27" data-marpit-pagination-total="28" style="--class:lead;--paginate:true;--theme:gaia;--marpit-advanced-background-split:33%;" data-marpit-advanced-background="content" data-marpit-advanced-background-split="left">
<h1>И только Kotlin <img class="emoji" draggable="false" alt="❤️" src="https://twemoji.maxcdn.com/2/svg/2764.svg" data-marp-twemoji=""/></h1>
<p>Всё unchecked, но если <strong>очень надо™</strong> — то есть аннотация <code>@Throws</code></p>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="lead" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="27" data-marpit-pagination-total="28"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-class="lead invert" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead invert" data-marpit-pagination="28" data-marpit-pagination-total="28" style="--class:lead invert;--paginate:true;--theme:gaia;" data-marpit-advanced-background="background"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;https://source.unsplash.com/p1SKuYXxqec&quot;);"></figure></div></section></foreignObject><foreignObject width="1280" height="720"><section id="28" data-class="lead invert" data-paginate="true" data-footer="@asm0di0 at Twitter&amp;emsp13;&amp;emsp13;@asm0dey at Telegram&amp;emsp13;&amp;emsp13;#MoscowPythonConf" data-theme="gaia" class="lead invert" data-marpit-pagination="28" data-marpit-pagination-total="28" style="--class:lead invert;--paginate:true;--theme:gaia;" data-marpit-advanced-background="content">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Экосистема</span></foreignObject></svg></h1>
<footer>@asm0di0 at Twitter  @asm0dey at Telegram  #MoscowPythonConf</footer>
</section>
<script>!function(){"use strict";const t=()=>"Apple Computer, Inc."===navigator.vendor?[e]:[];function e(t){Array.from(document.getElementsByTagName("svg"),e=>{if(e.hasAttribute("data-marpit-svg")){const{clientHeight:r,clientWidth:a}=e;e.style.transform||(e.style.transform="translateZ(0)");const o=t||e.currentScale||1,i=e.viewBox.baseVal.width/o,n=e.viewBox.baseVal.height/o,s=Math.min(r/n,a/i);Array.from(e.querySelectorAll(":scope > foreignObject"),t=>{const e=t.x.baseVal.value,o=t.y.baseVal.value;Array.from(t.querySelectorAll(":scope > section"),t=>{t.style.transformOrigin||(t.style.transformOrigin="0 0");const l=(a-s*i)/2-e,c=(r-s*n)/2-o;t.style.transform=`translate3d(${l}px,${c}px,0) scale(${s}) translate(${e}px,${o}px)`})})}})}const r="data-marp-fitting",a="data-marp-fitting-code",o="data-marp-fitting-math",i=(t,e,r)=>{if(t.getAttribute(e)!==r)return t.setAttribute(e,r),!0};function n(e=!0){for(const e of t())e();Array.from(document.querySelectorAll(`svg[${r}="svg"]`),t=>{const e=t.firstChild,r=e.firstChild,{scrollWidth:n,scrollHeight:s}=r;let l,c=1;if(t.hasAttribute(a)&&(l=t.parentElement.parentElement),t.hasAttribute(o)&&(l=t.parentElement),l){const t=getComputedStyle(l),e=Math.ceil(l.clientWidth-parseFloat(t.paddingLeft)-parseFloat(t.paddingRight));e&&(c=e)}const p=Math.max(n,c),d=Math.max(s,1),m=`0 0 ${p} ${d}`;i(e,"width",`${p}`),i(e,"height",`${d}`),i(t,"preserveAspectRatio",getComputedStyle(t).getPropertyValue("--preserve-aspect-ratio")||"xMinYMin meet"),i(t,"viewBox",m)&&t.classList.toggle("__reflow__")}),e&&window.requestAnimationFrame(()=>n(e))}!function(){if("undefined"==typeof window)throw new Error("Marp Core's browser script is valid only in browser context.");window.marpCoreBrowserScript?console.warn("Marp Core's browser script has already executed."):(Object.defineProperty(window,"marpCoreBrowserScript",{value:!0}),n())}()}();
</script></foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section class="lead invert" style="" data-marpit-advanced-background="pseudo" data-marpit-pagination="28" data-marpit-pagination-total="28"></section></foreignObject></svg></div><script>!function(){"use strict";var e={from:function(e,t){var n,r=1===(e.parent||e).nodeType?e.parent||e:document.querySelector(e.parent||e),o=[].filter.call("string"==typeof e.slides?r.querySelectorAll(e.slides):e.slides||r.children,(function(e){return"SCRIPT"!==e.nodeName})),s={},a=function(e,t){return(t=t||{}).index=o.indexOf(e),t.slide=e,t},i=function(e,t){s[e]=(s[e]||[]).filter((function(e){return e!==t}))},c=function(e,t){return(s[e]||[]).reduce((function(e,n){return e&&!1!==n(t)}),!0)},l=function(e,t){o[e]&&(n&&c("deactivate",a(n,t)),n=o[e],c("activate",a(n,t)))},d=function(e,t){var r=o.indexOf(n)+e;c(e>0?"next":"prev",a(n,t))&&l(r,t)},u={off:i,on:function(e,t){return(s[e]||(s[e]=[])).push(t),i.bind(null,e,t)},fire:c,slide:function(e,t){if(!arguments.length)return o.indexOf(n);c("slide",a(o[e],t))&&l(e,t)},next:d.bind(null,1),prev:d.bind(null,-1),parent:r,slides:o,destroy:function(e){c("destroy",a(n,e)),s={}}};return(t||[]).forEach((function(e){e(u)})),n||l(0),u}};function t(e){e.parent.classList.add("bespoke-marp-parent"),e.slides.map(e=>e.classList.add("bespoke-marp-slide")),e.on("activate",t=>{e.slides.map(e=>e.classList.remove("bespoke-marp-active")),t.slide.classList.add("bespoke-marp-active")})}function n(e=2e3){return t=>{let n;function r(){n&&clearTimeout(n),n=setTimeout(()=>{t.parent.classList.add("bespoke-marp-inactive")},e),t.parent.classList.remove("bespoke-marp-inactive")}document.addEventListener("mousedown",r),document.addEventListener("mousemove",r),document.addEventListener("touchend",r),setTimeout(r,0)}}const r=["AUDIO","BUTTON","INPUT","SELECT","TEXTAREA","VIDEO"];function o(e){e.parent.addEventListener("keydown",e=>{if(!e.target)return;const t=e.target;(r.includes(t.nodeName)||"true"===t.contentEditable)&&e.stopPropagation()})}function s(e){window.addEventListener("load",()=>{for(const t of e.slides){const e=t.querySelector("[data-marp-fitting]")?"":"hideable";t.setAttribute("data-bespoke-marp-load",e)}})}function a(e){let t=0,n=0;Object.defineProperty(e,"fragments",{enumerable:!0,value:e.slides.map(e=>[null,...e.querySelectorAll("[data-marpit-fragment]")])});const r=r=>void 0!==e.fragments[t][n+r],o=(r,o)=>{t=r,n=o,e.fragments.forEach((e,t)=>{e.forEach((e,n)=>{if(null==e)return;const s=t<r||t===r&&n<=o;e.setAttribute("data-bespoke-marp-fragment",s?"active":"inactive"),t===r&&n===o?e.setAttribute("data-bespoke-marp-current-fragment","current"):e.removeAttribute("data-bespoke-marp-current-fragment")})}),e.fragmentIndex=o;const s={slide:e.slides[r],index:r,fragments:e.fragments[r],fragmentIndex:o};e.fire("fragment",s)};e.on("next",()=>{if(r(1))return o(t,n+1),!1;const s=t+1;e.fragments[s]&&o(s,0)}),e.on("prev",()=>{if(r(-1))return o(t,n-1),!1;const s=t-1;e.fragments[s]&&o(s,e.fragments[s].length-1)}),e.on("slide",({index:t,fragment:n})=>{let r=0;if(void 0!==n){const o=e.fragments[t];if(o){const{length:e}=o;r=-1===n?e-1:Math.min(Math.max(n,0),e-1)}}o(t,r)}),o(0,0)}var i,c=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e){
/*!
* screenfull
* v5.0.0 - 2019-09-09
* (c) Sindre Sorhus; MIT License
*/
!function(){var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},n=e.exports,r=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],r=0,o=n.length,s={};r<o;r++)if((e=n[r])&&e[1]in t){for(r=0;r<e.length;r++)s[n[0][r]]=e[r];return s}return!1}(),o={change:r.fullscreenchange,error:r.fullscreenerror},s={request:function(e){return new Promise(function(n,o){var s=function(){this.off("change",s),n()}.bind(this);this.on("change",s),e=e||t.documentElement,Promise.resolve(e[r.requestFullscreen]()).catch(o)}.bind(this))},exit:function(){return new Promise(function(e,n){if(this.isFullscreen){var o=function(){this.off("change",o),e()}.bind(this);this.on("change",o),Promise.resolve(t[r.exitFullscreen]()).catch(n)}else e()}.bind(this))},toggle:function(e){return this.isFullscreen?this.exit():this.request(e)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){var r=o[e];r&&t.addEventListener(r,n,!1)},off:function(e,n){var r=o[e];r&&t.removeEventListener(r,n,!1)},raw:r};r?(Object.defineProperties(s,{isFullscreen:{get:function(){return Boolean(t[r.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[r.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[r.fullscreenEnabled])}}}),n?e.exports=s:window.screenfull=s):n?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()}));c.isEnabled;function l(e){e.fullscreen=()=>{c.isEnabled&&c.toggle(document.body)},document.addEventListener("keydown",t=>{70!==t.which&&122!==t.which||t.altKey||t.ctrlKey||t.metaKey||!c.isEnabled||(e.fullscreen(),t.preventDefault())})}function d(e={}){const t=Object.assign({interval:200},e);return e=>{document.addEventListener("keydown",t=>{(32===t.which&&t.shiftKey||33===t.which||37===t.which||38===t.which)&&e.prev(),(32===t.which&&!t.shiftKey||34===t.which||39===t.which||40===t.which)&&e.next(),35===t.which&&e.slide(e.slides.length-1,{fragment:-1}),36===t.which&&e.slide(0)});let n,r,o=0;e.parent.addEventListener("wheel",s=>{let a=!1;const c=(e,t)=>{var n;e&&(a=a||function(e,t){return function(e,t){const n=t===i.X?"Width":"Height";return e[`client${n}`]<e[`scroll${n}`]}(e,t)&&function(e,t){const{overflow:n}=e,r=e[`overflow${t}`];return"auto"===n||"scroll"===n||"auto"===r||"scroll"===r}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */(getComputedStyle(e),t)}(e,t)),(null===(n=e)||void 0===n?void 0:n.parentElement)&&c(e.parentElement,t)};if(0!==s.deltaX&&c(s.target,i.X),0!==s.deltaY&&c(s.target,i.Y),a)return;s.preventDefault(),r&&clearTimeout(r),r=setTimeout(()=>{n=0},t.interval);const l=Date.now()-o<t.interval,d=Math.sqrt(Math.pow(s.deltaX,2)+Math.pow(s.deltaY,2)),u=d<=n;if(n=d,l||u)return;let f;(s.deltaX>0||s.deltaY>0)&&(f="next"),(s.deltaX<0||s.deltaY<0)&&(f="prev"),f&&(e[f](),o=Date.now())})}}function u(e=".bespoke-marp-osc"){const t=document.querySelector(e);if(!t)return()=>{};const n=(e,n)=>{t.querySelectorAll(`[data-bespoke-marp-osc=${JSON.stringify(e)}]`).forEach(n)};return c.isEnabled||n("fullscreen",e=>e.style.display="none"),e=>{t.addEventListener("click",t=>{if(t.target instanceof HTMLElement){const{bespokeMarpOsc:n}=t.target.dataset;switch(n&&t.target.blur(),n){case"next":e.next();break;case"prev":e.prev();break;case"fullscreen":"function"==typeof e.fullscreen&&c.isEnabled&&e.fullscreen();break;case"presenter":(()=>(function(e,t,n,r){return new(n||(n=Promise))((function(o,s){function a(e){try{c(r.next(e))}catch(e){s(e)}}function i(e){try{c(r.throw(e))}catch(e){s(e)}}function c(e){e.done?o(e.value):new n((function(t){t(e.value)})).then(a,i)}c((r=r.apply(e,t||[])).next())}))})(this,void 0,void 0,(function*(){c.isEnabled&&c.isFullscreen&&(yield c.exit()),e.openPresenterView()})))()}}}),e.parent.appendChild(t),e.on("activate",({index:t})=>{n("page",n=>n.textContent=`Page ${t+1} of ${e.slides.length}`)}),e.on("fragment",({index:t,fragments:r,fragmentIndex:o})=>{n("prev",e=>e.disabled=0===t&&0===o),n("next",n=>n.disabled=t===e.slides.length-1&&o===r.length-1)}),c.isEnabled&&c.onchange(()=>n("fullscreen",e=>e.classList.toggle("exit",c.isEnabled&&c.isFullscreen)))}}!function(e){e.X="X",e.Y="Y"}(i||(i={}));const f=(...e)=>history.replaceState(...e);var m;!function(e){e.Normal="",e.Presenter="presenter",e.Next="next"}(m||(m={}));const p=(e,{protocol:t,host:n,pathname:r,hash:o}=location)=>{const s=e.toString();return`${t}//${n}${r}${s?"?":""}${s}${o}`},h=()=>{switch(document.body.getAttribute("data-bespoke-view")){case m.Normal:return m.Normal;case m.Presenter:return m.Presenter;case m.Next:return m.Next;default:throw new Error("View mode is not assigned.")}},g=e=>new URLSearchParams(location.search).get(e),v=e=>{const t=g(e);return b({[e]:void 0}),t},b=(e,t={})=>{const n=Object.assign({location:location,setter:f},t),r=new URLSearchParams(n.location.search);for(const t of Object.keys(e)){const n=e[t];"string"==typeof n?r.set(t,n):r.delete(t)}try{n.setter(null,document.title,p(r,n.location))}catch(e){console.error(e)}},w=()=>document.body.setAttribute("data-bespoke-view",(()=>{switch(g("view")){case"next":return m.Next;case"presenter":return m.Presenter;default:return m.Normal}})());const x=e=>e.syncKey&&"string"==typeof e.syncKey;function y(){const e=Math.max(Math.floor(.85*window.innerWidth),640),t=Math.max(Math.floor(.85*window.innerHeight),360);return window.open(this.presenterUrl,`bespoke-marp-presenter-${this.syncKey}`,`width=${e},height=${t},menubar=no,toolbar=no`)}function E(){const e=new URLSearchParams(location.search);return e.set("view","presenter"),e.set("sync",this.syncKey),p(e)}function k(e){const{title:t}=document;document.title=`[Presenter view]${t?` - ${t}`:""}`;const n=function(e){const t=document.createElement("div");return t.className="bespoke-marp-presenter-container",t.appendChild(e),t}(e.parent);n.appendChild(function(e){const t=document.createElement("div");t.className="bespoke-marp-presenter-next-container",t.addEventListener("click",()=>e.next());const n=document.createElement("iframe"),r=(o=n,(e,t)=>o.contentWindow.postMessage(`navigate:${e},${t}`,"null"===window.origin?"*":window.origin));var o;return n.addEventListener("load",()=>{t.classList.add("active"),r(e.slide(),e.fragmentIndex),e.on("fragment",({index:e,fragmentIndex:t})=>r(e,t))}),n.className="bespoke-marp-presenter-next",n.src="?view=next",t.appendChild(n),t}(e)),n.appendChild(function(e){const t=document.querySelectorAll(".bespoke-marp-note"),n=document.createElement("div");return n.className="bespoke-marp-presenter-note-container",t.forEach(e=>{e.addEventListener("keydown",e=>e.stopPropagation()),n.appendChild(e)}),e.on("activate",()=>t.forEach(t=>t.classList.toggle("active",t.dataset.index==e.slide()))),n}(e));const r=function(){const e=document.createElement("div");return e.className="bespoke-marp-presenter-info-container",e}();r.appendChild(function(e){const t=document.createElement("div");t.className="bespoke-marp-presenter-info-page";const n=document.createElement("span");n.className="bespoke-marp-presenter-info-page-text",e.on("activate",({index:t})=>{n.textContent=`${t+1} / ${e.slides.length}`});const r=document.createElement("button");r.className="bespoke-marp-presenter-info-page-prev",r.tabIndex=-1,r.textContent="Previous",r.title="Previous",r.addEventListener("click",()=>{r.blur(),e.prev()});const o=document.createElement("button");return o.className="bespoke-marp-presenter-info-page-next",o.tabIndex=-1,o.textContent="Next",o.title="Next",o.addEventListener("click",()=>{o.blur(),e.next()}),e.on("fragment",({index:t,fragments:n,fragmentIndex:s})=>{r.disabled=0===t&&0===s,o.disabled=t===e.slides.length-1&&s===n.length-1}),t.appendChild(r),t.appendChild(n),t.appendChild(o),t}(e)),r.appendChild(function(){const e=document.createElement("time");e.title="Current time",e.className="bespoke-marp-presenter-info-time";const t=()=>e.textContent=(new Date).toLocaleTimeString();return t(),setInterval(t,250),e}()),r.appendChild(function(){const e=document.createElement("div");return e.className="bespoke-marp-presenter-info-timer",e.textContent="Start timer",e}()),n.appendChild(r),document.body.appendChild(n)}function L(e){const t=h();return t===m.Next&&e.appendChild(document.createElement("span")),e=>{t===m.Normal&&function(e){if(!x(e))throw new Error("The current instance of Bespoke.js is invalid for Marp bespoke presenter plugin.");Object.defineProperties(e,{openPresenterView:{enumerable:!0,value:y},presenterUrl:{enumerable:!0,get:E}}),document.addEventListener("keydown",t=>{80!==t.which||t.altKey||t.ctrlKey||t.metaKey||(t.preventDefault(),e.openPresenterView())})}(e),t===m.Presenter&&k(e),t===m.Next&&function(e){window.addEventListener("message",t=>{if(t.origin!==window.origin)return;const[n,r]=t.data.split(":");if("navigate"===n){const[t,n]=r.split(",");e.slide(Number.parseInt(t,10),{fragment:Number.parseInt(n,10)}),e.next()}})}(e)}}const N=".bespoke-progress-bar";function S(e){e.on("activate",t=>{document.querySelectorAll(N).forEach(n=>{n.style.flexBasis=`${100*t.index/(e.slides.length-1)}%`})})}const P=e=>{const t=Number.parseInt(e,10);return Number.isNaN(t)?null:t};function I(e={}){const t=Object.assign({history:!0},e);return e=>{let n=!0;const r=e=>{const t=n;try{return n=!0,e()}finally{n=t}},o=(t={fragment:!0})=>{((t,n)=>{const{fragments:r,slides:o}=e,s=Math.max(0,Math.min(t,o.length-1)),a=Math.max(0,Math.min(n||0,r[s].length-1));s===e.slide()&&a===e.fragmentIndex||e.slide(s,{fragment:a})})((P(location.hash.slice(1))||1)-1,t.fragment?P(g("f")||""):null)};e.on("fragment",({index:e,fragmentIndex:r})=>{n||b({f:0===r||r.toString()},{location:Object.assign(Object.assign({},location),{hash:`#${e+1}`}),setter:(...e)=>t.history?history.pushState(...e):history.replaceState(...e)})}),setTimeout(()=>{o(),window.addEventListener("hashchange",()=>r(()=>{o({fragment:!1}),b({f:void 0})})),window.addEventListener("popstate",()=>{n||r(()=>o())}),n=!1},0)}}var C=self.crypto||self.msCrypto,M=function(e){e=e||21;for(var t="",n=C.getRandomValues(new Uint8Array(e));e--;)t+="QLUint8ARdomValuesObj0h6345-79BCrypgJzHKTNYDSMkXPZ_FfG1WcqvwxEI2"[63&n[e]];return t};function F(e={}){const t=e.key||M(),n=`bespoke-marp-sync-${t}`,r=()=>{const e=localStorage.getItem(n);return e?JSON.parse(e):Object.create(null)},o=e=>{const t=r(),o=Object.assign(Object.assign({},t),e(t));return localStorage.setItem(n,JSON.stringify(o)),o};return o(e=>({reference:(e.reference||0)+1})),e=>{Object.defineProperty(e,"syncKey",{value:t,enumerable:!0});let s=!0;setTimeout(()=>{e.on("fragment",e=>{s&&o(()=>({index:e.index,fragmentIndex:e.fragmentIndex}))})},0),window.addEventListener("storage",t=>{if(t.key===n&&t.oldValue&&t.newValue){const n=JSON.parse(t.oldValue),r=JSON.parse(t.newValue);if(n.index!==r.index||n.fragmentIndex!==r.fragmentIndex)try{s=!1,e.slide(r.index,{fragment:r.fragmentIndex})}finally{s=!0}}}),e.on("destroy",()=>{const{reference:e}=r();void 0===e||e<=1?localStorage.removeItem(n):o(()=>({reference:e-1}))})}}function O(e={}){const t=Object.assign({slope:Math.tan(-35*Math.PI/180),swipeThreshold:30},e);return e=>{let n;const r=e.parent,o=e=>{const t=r.getBoundingClientRect();return{x:e.pageX-(t.left+t.right)/2,y:e.pageY-(t.top+t.bottom)/2}};r.addEventListener("touchstart",e=>{n=1===e.touches.length?o(e.touches[0]):void 0}),r.addEventListener("touchmove",e=>{if(n)if(1===e.touches.length){e.preventDefault();const t=o(e.touches[0]),r=t.x-n.x,s=t.y-n.y;n.delta=Math.sqrt(Math.pow(Math.abs(r),2)+Math.pow(Math.abs(s),2)),n.radian=Math.atan2(r,s)}else n=void 0}),r.addEventListener("touchend",r=>{if(n){if(n.delta&&n.delta>=t.swipeThreshold){let o=n.radian-t.slope;o=(o+Math.PI)%(2*Math.PI)-Math.PI,e[o<0?"next":"prev"](),r.stopPropagation()}n=void 0}})}}const $=[m.Normal,m.Presenter,m.Next],T=(...e)=>{const t=$.findIndex(e=>h()===e);if(t<0)throw new Error("Invalid view");return e.map(([e,n])=>e[t]&&n).filter(e=>e)};!function(r=document.getElementById("p")){w();const i=v("sync")||void 0,c=!1,f=!0,m=e.from(r,T([[f,f,c],F({key:i})],[[f,f,f],L(r)],[[f,f,c],o],[[f,f,f],t],[[f,c,c],n()],[[f,f,f],s],[[f,f,f],I({history:!1})],[[f,f,c],d()],[[f,f,c],l],[[f,c,c],S],[[f,f,c],O()],[[f,c,c],u()],[[f,f,f],a]));window.addEventListener("beforeunload",()=>b({sync:m.syncKey})),window.addEventListener("unload",()=>m.destroy())}()}();
</script></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment