Mercurial > hg > Papers > 2021 > anatofuz-master
view slide/index.html @ 136:fe84812351e0
update
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Feb 2021 11:01:31 +0900 |
parents | 58a8b3df7e9b |
children | c6247127e7f4 |
line wrap: on
line source
<!DOCTYPE html><html lang="en-US"><head><title>GearsOSのメタ計算</title><meta property="og:title" content="GearsOSのメタ計算"><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;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;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){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{content-visibility:hidden;z-index:-1;pointer-events:none;opacity:0}svg.bespoke-marp-slide.bespoke-marp-active{content-visibility:visible;z-index:0;pointer-events:auto;opacity:1}svg.bespoke-marp-slide.bespoke-marp-active.bespoke-marp-active-ready *{-webkit-animation-name:__bespoke_marp__!important;animation-name:__bespoke_marp__!important}@supports not (content-visibility:hidden){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;transform:translateX(-50%);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: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{flex:0 0 0;background:#0288d1;transition: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{font-family:Helvetica,Arial,sans-serif;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{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;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:#eee;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;font-size:1.1em;overflow:auto;padding-right:3px;white-space:pre-wrap;word-wrap:break-word;scrollbar-width:thin;scrollbar-color:hsla(0,0%,93.3%,.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%,93.3%,.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{align-items:center;box-sizing:border-box;color:#eee;display:flex;flex-wrap:nowrap;grid-area:info;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{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;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;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>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;animation-delay:0s!important;animation-duration:0s!important;color-adjust:exact!important;transition:none!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 default theme. * * @theme default * @author Yuki Hattori * * @auto-scaling true * @size 4:3 960px 720px */div#p>svg>foreignObject>section .octicon{display:inline-block;fill:currentColor;vertical-align:text-bottom}div#p>svg>foreignObject>section .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}div#p>svg>foreignObject>section .anchor:focus{outline:none}div#p>svg>foreignObject>section h1 .octicon-link,div#p>svg>foreignObject>section h2 .octicon-link,div#p>svg>foreignObject>section h3 .octicon-link,div#p>svg>foreignObject>section h4 .octicon-link,div#p>svg>foreignObject>section h5 .octicon-link,div#p>svg>foreignObject>section h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}div#p>svg>foreignObject>section h1:hover .anchor,div#p>svg>foreignObject>section h2:hover .anchor,div#p>svg>foreignObject>section h3:hover .anchor,div#p>svg>foreignObject>section h4:hover .anchor,div#p>svg>foreignObject>section h5:hover .anchor,div#p>svg>foreignObject>section h6:hover .anchor{text-decoration:none}div#p>svg>foreignObject>section h1:hover .anchor .octicon-link,div#p>svg>foreignObject>section h2:hover .anchor .octicon-link,div#p>svg>foreignObject>section h3:hover .anchor .octicon-link,div#p>svg>foreignObject>section h4:hover .anchor .octicon-link,div#p>svg>foreignObject>section h5:hover .anchor .octicon-link,div#p>svg>foreignObject>section h6:hover .anchor .octicon-link{visibility:visible}div#p>svg>foreignObject>section h1:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h2:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h3:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h4:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h5:hover .anchor .octicon-link:before,div#p>svg>foreignObject>section h6:hover .anchor .octicon-link:before{width:16px;height:16px;content:" ";display:inline-block;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'/%3E%3C/svg%3E")}div#p>svg>foreignObject>section{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;font-size:16px;line-height:1.5;word-wrap:break-word}div#p>svg>foreignObject>section{--marpit-root-font-size:16px}div#p>svg>foreignObject>section details{display:block}div#p>svg>foreignObject>section summary{display:list-item}div#p>svg>foreignObject>section a{background-color:initial}div#p>svg>foreignObject>section a:active,div#p>svg>foreignObject>section a:hover{outline-width:0}div#p>svg>foreignObject>section strong{font-weight:inherit;font-weight:bolder}div#p>svg>foreignObject>section h1{margin:.67em 0}div#p>svg>foreignObject>section img{border-style:none}div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section kbd,div#p>svg>foreignObject>section pre{font-family:monospace,monospace;font-size:1em}div#p>svg>foreignObject>section hr{box-sizing:initial;overflow:visible}div#p>svg>foreignObject>section input{font:inherit;margin:0;overflow:visible}div#p>svg>foreignObject>section [type=checkbox]{padding:0}div#p>svg>foreignObject>section *,div#p>svg>foreignObject>section [type=checkbox]{box-sizing:border-box}div#p>svg>foreignObject>section input{font-family:inherit;font-size:inherit;line-height:inherit}div#p>svg>foreignObject>section a{color:#0366d6;text-decoration:none}div#p>svg>foreignObject>section a:hover{text-decoration:underline}div#p>svg>foreignObject>section strong{font-weight:600}div#p>svg>foreignObject>section hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border-bottom:1px solid #dfe2e5}div#p>svg>foreignObject>section hr:after,div#p>svg>foreignObject>section hr:before{display:table;content:""}div#p>svg>foreignObject>section hr:after{clear:both}div#p>svg>foreignObject>section table{border-spacing:0;border-collapse:collapse}div#p>svg>foreignObject>section td,div#p>svg>foreignObject>section th{padding:0}div#p>svg>foreignObject>section details summary{cursor:pointer}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-top:0;margin-bottom:0}div#p>svg>foreignObject>section h1{font-size:32px}div#p>svg>foreignObject>section h1,div#p>svg>foreignObject>section h2{font-weight:600}div#p>svg>foreignObject>section h2{font-size:24px}div#p>svg>foreignObject>section h3{font-size:20px}div#p>svg>foreignObject>section h3,div#p>svg>foreignObject>section h4{font-weight:600}div#p>svg>foreignObject>section h4{font-size:16px}div#p>svg>foreignObject>section h5{font-size:14px}div#p>svg>foreignObject>section h5,div#p>svg>foreignObject>section h6{font-weight:600}div#p>svg>foreignObject>section h6{font-size:12px}div#p>svg>foreignObject>section p{margin-top:0;margin-bottom:10px}div#p>svg>foreignObject>section blockquote{margin:0}div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{padding-left:0;margin-top:0;margin-bottom:0}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ul ol{list-style-type:lower-roman}div#p>svg>foreignObject>section ol ol ol,div#p>svg>foreignObject>section ol ul ol,div#p>svg>foreignObject>section ul ol ol,div#p>svg>foreignObject>section ul ul ol{list-style-type:lower-alpha}div#p>svg>foreignObject>section dd{margin-left:0}div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section pre{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px}div#p>svg>foreignObject>section pre{margin-top:0;margin-bottom:0}div#p>svg>foreignObject>section input::-webkit-inner-spin-button,div#p>svg>foreignObject>section input::-webkit-outer-spin-button{margin:0;-webkit-appearance:none;appearance:none}div#p>svg>foreignObject>section :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}div#p>svg>foreignObject>section .border{border:1px solid #e1e4e8!important}div#p>svg>foreignObject>section .border-0{border:0!important}div#p>svg>foreignObject>section .border-bottom{border-bottom:1px solid #e1e4e8!important}div#p>svg>foreignObject>section .rounded-1{border-radius:3px!important}div#p>svg>foreignObject>section .bg-white{background-color:#fff!important}div#p>svg>foreignObject>section .bg-gray-light{background-color:#fafbfc!important}div#p>svg>foreignObject>section .text-gray-light{color:#6a737d!important}div#p>svg>foreignObject>section .pl-3,div#p>svg>foreignObject>section .px-3{padding-left:16px!important}div#p>svg>foreignObject>section .px-3{padding-right:16px!important}div#p>svg>foreignObject>section .f6{font-size:12px!important}div#p>svg>foreignObject>section div#p>svg>foreignObject>section section.f6{--marpit-root-font-size:12px!important}div#p>svg>foreignObject>section .lh-condensed{line-height:1.25!important}div#p>svg>foreignObject>section .text-bold{font-weight:600!important}div#p>svg>foreignObject>section .pl-c{color:#6a737d}div#p>svg>foreignObject>section .pl-c1,div#p>svg>foreignObject>section .pl-s .pl-v{color:#005cc5}div#p>svg>foreignObject>section .pl-e,div#p>svg>foreignObject>section .pl-en{color:#6f42c1}div#p>svg>foreignObject>section .pl-s .pl-s1,div#p>svg>foreignObject>section .pl-smi{color:#24292e}div#p>svg>foreignObject>section .pl-ent{color:#22863a}div#p>svg>foreignObject>section .pl-k{color:#d73a49}div#p>svg>foreignObject>section .pl-pds,div#p>svg>foreignObject>section .pl-s,div#p>svg>foreignObject>section .pl-s .pl-pse .pl-s1,div#p>svg>foreignObject>section .pl-sr,div#p>svg>foreignObject>section .pl-sr .pl-cce,div#p>svg>foreignObject>section .pl-sr .pl-sra,div#p>svg>foreignObject>section .pl-sr .pl-sre{color:#032f62}div#p>svg>foreignObject>section .pl-smw,div#p>svg>foreignObject>section .pl-v{color:#e36209}div#p>svg>foreignObject>section .pl-bu{color:#b31d28}div#p>svg>foreignObject>section .pl-ii{color:#fafbfc;background-color:#b31d28}div#p>svg>foreignObject>section .pl-c2{color:#fafbfc;background-color:#d73a49}div#p>svg>foreignObject>section .pl-c2:before{content:"^M"}div#p>svg>foreignObject>section .pl-sr .pl-cce{font-weight:700;color:#22863a}div#p>svg>foreignObject>section .pl-ml{color:#735c0f}div#p>svg>foreignObject>section .pl-mh,div#p>svg>foreignObject>section .pl-mh .pl-en,div#p>svg>foreignObject>section .pl-ms{font-weight:700;color:#005cc5}div#p>svg>foreignObject>section .pl-mi{font-style:italic;color:#24292e}div#p>svg>foreignObject>section .pl-mb{font-weight:700;color:#24292e}div#p>svg>foreignObject>section .pl-md{color:#b31d28;background-color:#ffeef0}div#p>svg>foreignObject>section .pl-mi1{color:#22863a;background-color:#f0fff4}div#p>svg>foreignObject>section .pl-mc{color:#e36209;background-color:#ffebda}div#p>svg>foreignObject>section .pl-mi2{color:#f6f8fa;background-color:#005cc5}div#p>svg>foreignObject>section .pl-mdr{font-weight:700;color:#6f42c1}div#p>svg>foreignObject>section .pl-ba{color:#586069}div#p>svg>foreignObject>section .pl-sg{color:#959da5}div#p>svg>foreignObject>section .pl-corl{text-decoration:underline;color:#032f62}div#p>svg>foreignObject>section .mb-0{margin-bottom:0!important}div#p>svg>foreignObject>section .my-2{margin-bottom:8px!important;margin-top:8px!important}div#p>svg>foreignObject>section .pl-0{padding-left:0!important}div#p>svg>foreignObject>section .py-0{padding-top:0!important;padding-bottom:0!important}div#p>svg>foreignObject>section .pl-1{padding-left:4px!important}div#p>svg>foreignObject>section .pl-2{padding-left:8px!important}div#p>svg>foreignObject>section .py-2{padding-top:8px!important;padding-bottom:8px!important}div#p>svg>foreignObject>section .pl-3{padding-left:16px!important}div#p>svg>foreignObject>section .pl-4{padding-left:24px!important}div#p>svg>foreignObject>section .pl-5{padding-left:32px!important}div#p>svg>foreignObject>section .pl-6{padding-left:40px!important}div#p>svg>foreignObject>section .pl-7{padding-left:48px!important}div#p>svg>foreignObject>section .pl-8{padding-left:64px!important}div#p>svg>foreignObject>section .pl-9{padding-left:80px!important}div#p>svg>foreignObject>section .pl-10{padding-left:96px!important}div#p>svg>foreignObject>section .pl-11{padding-left:112px!important}div#p>svg>foreignObject>section .pl-12{padding-left:128px!important}div#p>svg>foreignObject>section hr{border-bottom-color:#eee}div#p>svg>foreignObject>section kbd{display:inline-block;padding:3px 5px;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:1px solid #d1d5da;border-radius:3px;box-shadow:inset 0 -1px 0 #d1d5da}div#p>svg>foreignObject>section:after,div#p>svg>foreignObject>section:before{display:table /* content:""; */}div#p>svg>foreignObject>section:after{clear:both}div#p>svg>foreignObject>section>:first-child{margin-top:0!important}div#p>svg>foreignObject>section>:last-child{margin-bottom:0!important}div#p>svg>foreignObject>section a:not([href]){color:inherit;text-decoration:none}div#p>svg>foreignObject>section blockquote,div#p>svg>foreignObject>section details,div#p>svg>foreignObject>section dl,div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section p,div#p>svg>foreignObject>section pre,div#p>svg>foreignObject>section table,div#p>svg>foreignObject>section ul{margin-top:0;margin-bottom:16px}div#p>svg>foreignObject>section hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}div#p>svg>foreignObject>section blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}div#p>svg>foreignObject>section blockquote>:first-child{margin-top:0}div#p>svg>foreignObject>section blockquote>:last-child{margin-bottom:0}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-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}div#p>svg>foreignObject>section h1{font-size:2em}div#p>svg>foreignObject>section h1,div#p>svg>foreignObject>section h2{padding-bottom:.3em;border-bottom:1px solid #eaecef}div#p>svg>foreignObject>section h2{font-size:1.5em}div#p>svg>foreignObject>section h3{font-size:1.25em}div#p>svg>foreignObject>section h4{font-size:1em}div#p>svg>foreignObject>section h5{font-size:.875em}div#p>svg>foreignObject>section h6{font-size:.85em;color:#6a737d}div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{padding-left:2em}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ol ul,div#p>svg>foreignObject>section ul ol,div#p>svg>foreignObject>section ul ul{margin-top:0;margin-bottom:0}div#p>svg>foreignObject>section li{word-wrap:break-all}div#p>svg>foreignObject>section li>p{margin-top:16px}div#p>svg>foreignObject>section li+li{margin-top:.25em}div#p>svg>foreignObject>section dl{padding:0}div#p>svg>foreignObject>section dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}div#p>svg>foreignObject>section dl dd{padding:0 16px;margin-bottom:16px}div#p>svg>foreignObject>section table{display:block;width:100%;overflow:auto}div#p>svg>foreignObject>section table th{font-weight:600}div#p>svg>foreignObject>section table td,div#p>svg>foreignObject>section table th{padding:6px 13px;border:1px solid #dfe2e5}div#p>svg>foreignObject>section table tr{background-color:#fff;border-top:1px solid #c6cbd1}div#p>svg>foreignObject>section table tr:nth-child(2n){background-color:#f6f8fa}div#p>svg>foreignObject>section img{max-width:100%;box-sizing:initial;background-color:#fff}div#p>svg>foreignObject>section img[align=right]{padding-left:20px}div#p>svg>foreignObject>section img[align=left]{padding-right:20px}div#p>svg>foreignObject>section code{padding:.2em .4em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}div#p>svg>foreignObject>section pre{word-wrap:normal}div#p>svg>foreignObject>section pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}div#p>svg>foreignObject>section .highlight{margin-bottom:16px}div#p>svg>foreignObject>section .highlight pre{margin-bottom:0;word-break:normal}div#p>svg>foreignObject>section pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}div#p>svg>foreignObject>section pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:initial;border:0}div#p>svg>foreignObject>section .commit-tease-sha{display:inline-block;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:90%;color:#444d56}div#p>svg>foreignObject>section div#p>svg>foreignObject>section section.commit-tease-sha{--marpit-root-font-size:90%}div#p>svg>foreignObject>section .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}div#p>svg>foreignObject>section .blob-wrapper{overflow-x:auto;overflow-y:hidden}div#p>svg>foreignObject>section .blob-wrapper-embedded{max-height:240px;overflow-y:auto}div#p>svg>foreignObject>section .blob-num{width:1%;min-width:50px;padding-right:10px;padding-left:10px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;line-height:20px;color:rgba(27,31,35,.3);text-align:right;white-space:nowrap;vertical-align:top;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div#p>svg>foreignObject>section div#p>svg>foreignObject>section section.blob-num{--marpit-root-font-size:12px}div#p>svg>foreignObject>section .blob-num:hover{color:rgba(27,31,35,.6)}div#p>svg>foreignObject>section .blob-num:before{content:attr(data-line-number)}div#p>svg>foreignObject>section .blob-code{position:relative;padding-right:10px;padding-left:10px;line-height:20px;vertical-align:top}div#p>svg>foreignObject>section .blob-code-inner{overflow:visible;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;color:#24292e;word-wrap:normal;white-space:pre}div#p>svg>foreignObject>section div#p>svg>foreignObject>section section.blob-code-inner{--marpit-root-font-size:12px}div#p>svg>foreignObject>section .pl-token.active,div#p>svg>foreignObject>section .pl-token:hover{cursor:pointer;background:#ffea7f}div#p>svg>foreignObject>section .tab-size[data-tab-size="1"]{-moz-tab-size:1;-o-tab-size:1;tab-size:1}div#p>svg>foreignObject>section .tab-size[data-tab-size="2"]{-moz-tab-size:2;-o-tab-size:2;tab-size:2}div#p>svg>foreignObject>section .tab-size[data-tab-size="3"]{-moz-tab-size:3;-o-tab-size:3;tab-size:3}div#p>svg>foreignObject>section .tab-size[data-tab-size="4"]{-moz-tab-size:4;-o-tab-size:4;tab-size:4}div#p>svg>foreignObject>section .tab-size[data-tab-size="5"]{-moz-tab-size:5;-o-tab-size:5;tab-size:5}div#p>svg>foreignObject>section .tab-size[data-tab-size="6"]{-moz-tab-size:6;-o-tab-size:6;tab-size:6}div#p>svg>foreignObject>section .tab-size[data-tab-size="7"]{-moz-tab-size:7;-o-tab-size:7;tab-size:7}div#p>svg>foreignObject>section .tab-size[data-tab-size="8"]{-moz-tab-size:8;-o-tab-size:8;tab-size:8}div#p>svg>foreignObject>section .tab-size[data-tab-size="9"]{-moz-tab-size:9;-o-tab-size:9;tab-size:9}div#p>svg>foreignObject>section .tab-size[data-tab-size="10"]{-moz-tab-size:10;-o-tab-size:10;tab-size:10}div#p>svg>foreignObject>section .tab-size[data-tab-size="11"]{-moz-tab-size:11;-o-tab-size:11;tab-size:11}div#p>svg>foreignObject>section .tab-size[data-tab-size="12"]{-moz-tab-size:12;-o-tab-size:12;tab-size:12}div#p>svg>foreignObject>section .task-list-item{list-style-type:none}div#p>svg>foreignObject>section .task-list-item+.task-list-item{margin-top:3px}div#p>svg>foreignObject>section .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}div#p>svg>foreignObject>section .hljs{display:block;background:#fff;padding:.5em;color:#333;overflow-x:auto}div#p>svg>foreignObject>section .hljs-comment,div#p>svg>foreignObject>section .hljs-meta{color:#969896}div#p>svg>foreignObject>section .hljs-emphasis,div#p>svg>foreignObject>section .hljs-quote,div#p>svg>foreignObject>section .hljs-strong,div#p>svg>foreignObject>section .hljs-template-variable,div#p>svg>foreignObject>section .hljs-variable{color:#df5000}div#p>svg>foreignObject>section .hljs-keyword,div#p>svg>foreignObject>section .hljs-selector-tag,div#p>svg>foreignObject>section .hljs-type{color:#d73a49}div#p>svg>foreignObject>section .hljs-attribute,div#p>svg>foreignObject>section .hljs-bullet,div#p>svg>foreignObject>section .hljs-literal,div#p>svg>foreignObject>section .hljs-symbol{color:#0086b3}div#p>svg>foreignObject>section .hljs-name,div#p>svg>foreignObject>section .hljs-section{color:#63a35c}div#p>svg>foreignObject>section .hljs-tag{color:#333}div#p>svg>foreignObject>section .hljs-attr,div#p>svg>foreignObject>section .hljs-selector-attr,div#p>svg>foreignObject>section .hljs-selector-class,div#p>svg>foreignObject>section .hljs-selector-id,div#p>svg>foreignObject>section .hljs-selector-pseudo,div#p>svg>foreignObject>section .hljs-title{color:#6f42c1}div#p>svg>foreignObject>section .hljs-addition{color:#55a532;background-color:#eaffea}div#p>svg>foreignObject>section .hljs-deletion{color:#bd2c00;background-color:#ffecec}div#p>svg>foreignObject>section .hljs-link{text-decoration:underline}div#p>svg>foreignObject>section .hljs-number{color:#005cc5}div#p>svg>foreignObject>section .hljs-string{color:#032f62}div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{max-height:563px}div#p>svg>foreignObject>section h1{color:#246;font-size:1.6em}div#p>svg>foreignObject>section h1,div#p>svg>foreignObject>section h2{border-bottom:none}div#p>svg>foreignObject>section h2{font-size:1.3em}div#p>svg>foreignObject>section h3{font-size:1.1em}div#p>svg>foreignObject>section h4{font-size:1.05em}div#p>svg>foreignObject>section h5{font-size:1em}div#p>svg>foreignObject>section h6{font-size:.9em}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;color:#48c}div#p>svg>foreignObject>section hr{height:0;padding-top:.25em}div#p>svg>foreignObject>section pre{border:1px solid #999;line-height:1.15;overflow:visible}div#p>svg>foreignObject>section pre code svg[data-marp-fitting=svg]{max-height:529px}div#p>svg>foreignObject>section footer,div#p>svg>foreignObject>section header{margin:0;position:absolute;left:30px;color:hsla(0,0%,40%,.75);font-size:18px}div#p>svg>foreignObject>section header{top:21px}div#p>svg>foreignObject>section footer{bottom:21px}div#p>svg>foreignObject>section{align-items:stretch;background:#fff;display:flex;flex-direction:column;flex-wrap:nowrap;font-size:29px;height:720px;justify-content:center;padding:78.5px;width:1280px}div#p>svg>foreignObject>section{--marpit-root-font-size:29px}div#p>svg>foreignObject>section>:last-child,div#p>svg>foreignObject>section[data-footer]>:nth-last-child(2){margin-bottom:0}div#p>svg>foreignObject>section>:first-child,div#p>svg>foreignObject>section>header:first-child+*{margin-top:0}div#p>svg>foreignObject>section:after{position:absolute;padding:0;right:30px;bottom:21px;font-size:24px;color:#777}div#p>svg>foreignObject>section:after{--marpit-root-font-size:24px}div#p>svg>foreignObject>section.invert{background-color:#222;color:#e6eaf0}div#p>svg>foreignObject>section.invert:after{color:#999}div#p>svg>foreignObject>section.invert img{background-color:transparent}div#p>svg>foreignObject>section.invert a{color:#50b3ff}div#p>svg>foreignObject>section.invert h1{color:#a3c5e7}div#p>svg>foreignObject>section.invert h2,div#p>svg>foreignObject>section.invert h3,div#p>svg>foreignObject>section.invert h4,div#p>svg>foreignObject>section.invert h5{color:#ebeff5}div#p>svg>foreignObject>section.invert blockquote,div#p>svg>foreignObject>section.invert h6{border-color:#3d3f43;color:#939699}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:#7bf}div#p>svg>foreignObject>section.invert hr{background-color:#3d3f43}div#p>svg>foreignObject>section.invert footer,div#p>svg>foreignObject>section.invert header{color:hsla(0,0%,60%,.75)}div#p>svg>foreignObject>section.invert code,div#p>svg>foreignObject>section.invert kbd{background-color:#111}div#p>svg>foreignObject>section.invert kbd{border-color:#666;box-shadow:inset 0 -1px 0 #555;color:#e6eaf0}div#p>svg>foreignObject>section.invert table tr{background-color:#12181d;border-color:#60657b}div#p>svg>foreignObject>section.invert table tr:nth-child(2n){background-color:#1b2024}div#p>svg>foreignObject>section.invert table td,div#p>svg>foreignObject>section.invert table th{border-color:#5b5e61}div#p>svg>foreignObject>section.invert pre{background-color:#0a0e12;border-color:#777}div#p>svg>foreignObject>section.invert pre code{background-color:transparent}div#p>svg>foreignObject>section[data-color] h1,div#p>svg>foreignObject>section[data-color] h2,div#p>svg>foreignObject>section[data-color] h3,div#p>svg>foreignObject>section[data-color] h4,div#p>svg>foreignObject>section[data-color] h5,div#p>svg>foreignObject>section[data-color] h6{color:currentColor}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-paginate="true" data-marpit-pagination="1" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのメタ計算</h1> <ul> <li>清水 隆博 <ul> <li>琉球大学理工学研究科</li> <li>198584B</li> <li>河野研</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-marpit-pagination="2" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>研究発表の構成</h1> <ul> <li>研究目的</li> <li>CbC、GearsOSの基礎概念</li> <li>GearsOSの新機能</li> <li>本研究での新たなGearsOSのシステムの解説 <ul> <li>GearsOSのInterfaceシステムの改善</li> <li>Perlトランスパイラの改善</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-paginate="true" data-marpit-pagination="3" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>研究目的</h1> <ul> <li>OSとアプリケーションの信頼性の保証したい</li> <li>OSそのものも巨大なプログラム <ul> <li>プログラムの信頼性の保証にはテストが使われる</li> </ul> </li> <li>並列並行処理などのバグや、そもそもOSを構成する処理が巨大 <ul> <li>テストコードで信頼性を保証しきれない</li> </ul> </li> <li>形式手法を用いてテストに頼らず信頼性を保証したい <ul> <li>既存のソースコードに形式手法を導入できるフレームワークを構築したい</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-paginate="true" data-marpit-pagination="4" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルとメタレベルを用いた信頼性の向上</h1> <ul> <li>プログラムの実行部分は以下の2つからなる <ul> <li>入力と出力の関係を決める計算(ノーマルレベル)</li> <li>プログラムを実行したり、 信頼性を保証するために必要な計算(メタレベル)</li> </ul> </li> <li>メタレベルの例 <ul> <li>メモリやCPUの資源管理</li> <li>システムコールの動作(副作用)</li> <li>並行実行(他のプロセスとの干渉)</li> <li>モデル検査(可能な実行を列挙する方式の実行)</li> <li>証明(入力時と出力時の論理的な条件)、(invariant)</li> </ul> </li> <li>メタレベルの計算として信頼性を保証する</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-paginate="true" data-marpit-pagination="5" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマル、メタレベルの計算とGearsOS</h1> <ul> <li>ノーマル/メタレベルを一貫して記述できる言語にContinuation Based Cがある <ul> <li>CbCを用いてGearsOSを開発している</li> </ul> </li> <li>GearsOSではメタ計算の生成にトランスパイラを使っている <ul> <li>トランスパイラとはコードからコードを生成する処理系のこと</li> <li>生成しなければならないメタ計算の量が多いため、自動的に生成する</li> <li>CMakeとPerlでビルド時にノーマルレベルのコードをメタレベルに変換する</li> <li>ノーマルレベルで書いた記述がそのままコンパイルされる訳ではない</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-paginate="true" data-marpit-pagination="6" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのビルドシステム</h1> <ul> <li>CMakeとPerlを使ってビルドする <ul> <li>CMakeはMakefileやbuild.ninjaを生成する</li> <li>Perlは2種類のスクリプトが自動的に呼ばれる</li> </ul> </li> <li>Perlによってコード変換・ファイル生成が行われた後にコンパイルが走る <ul> <li>Perlの実行前はノーマルレベルだけのコード、実行後はメタが入る<br /> <img src="./geasflow1.svg" alt="w:632 h:10cm" style="width:632px;height:10cm;" /></li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-paginate="true" data-marpit-pagination="7" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのビルドシステム</h1> <ul> <li>Perlスクリプトはファイルの変換・生成を行う <ul> <li>メタ計算の変換・自動生成も行う</li> </ul> </li> <li>メタ計算で必要なファイル、データ構造も生成する <ul> <li>CodeGear/DataGearの番号など</li> </ul> </li> </ul> <p><img src="./geasflow1.svg" alt="w:632 h:10cm" style="width:632px;height:10cm;" /></p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-paginate="true" data-marpit-pagination="8" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマル、メタレベルの計算とGearsOS</h1> <ul> <li>トランスパイラで生成するメタレベルの計算をより拡張したい <ul> <li>手書きで実装しなければならなかったものを自動化したい</li> </ul> </li> <li>本研究ではトランスパイラでメタ計算を生成する機能を改善した <ul> <li>他にもメタ計算にまつわる様々な新機能をGearsOSに導入した</li> </ul> </li> </ul> <h2>主なGearsOSに導入された新機能</h2> <ul> <li>Interfaceシステムの強化</li> <li>手書きからの解放</li> <li>MetaCodeGearの入れ替え機能の追加</li> </ul> <p>まずGearsOSについて確認をしてから、新機能の解説を行う</p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-paginate="true" data-marpit-pagination="9" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルから見たGearsOSの構成</h1> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-paginate="true" data-marpit-pagination="10" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>CodeGear</h1> <ul> <li>CbCで定義する軽量継続で表現する単位をCodeGearと呼ぶ <ul> <li>呼び出すと元の関数に戻れない</li> </ul> </li> <li>Cの関数とアセンブラの中間の様に使える</li> <li>CodeGearは返り値の型の代わりに<code>__code</code>で宣言する</li> <li><code>goto CodeGear()</code>でCodeGearに継続する</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-paginate="true" data-marpit-pagination="11" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>DataGear</h1> <ul> <li>GearsOSで扱うデータの単位</li> <li>CodeGearの入出力はDataGearとして取り扱う</li> <li>InterfaceもDataGearとして扱われる</li> <li>Cの構造体の形でメタレベルでは表現される</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-paginate="true" data-marpit-pagination="12" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベル/メタレベルのCodeGear</h1> <ul> <li>ノーマルレベルのCodeGearから見ると、直接別のCodeGearに継続している</li> <li>実際はCodeGearの実行の前後にメタレベルの計算をするCodeGearが実行される <ul> <li>メタレベルの計算をするCodeGearをMetaCodeGearと呼ぶ</li> </ul> </li> </ul> <p><img src="./metacg.svg" alt="h:220 w:800" style="width:800px;height:220px;" /></p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-paginate="true" data-marpit-pagination="13" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルでのGearsOSの実装</h1> <ul> <li>次に継続するCodeGearを引数で受け取れる <ul> <li>この場合は次のCodeGear(<code>next</code>)に値(<code>data</code>)を書き込む</li> </ul> </li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pop</span><span class="hljs-params">(struct SingleLinkedStack* <span class="hljs-built_in">stack</span>, __code next(<span class="hljs-keyword">union</span> Data* data, ...))</span> </span>{ <span class="hljs-keyword">if</span> (<span class="hljs-built_in">stack</span>->top) { data = <span class="hljs-built_in">stack</span>->top->data; <span class="hljs-built_in">stack</span>->top = <span class="hljs-built_in">stack</span>->top->next; } <span class="hljs-keyword">else</span> { data = <span class="hljs-literal">NULL</span>; } <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">next</span><span class="hljs-params">(data, ...)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-paginate="true" data-marpit-pagination="14" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルでのGearsOSの実装</h1> <ul> <li>通常のプログラミング言語のように引数を受け取れる</li> <li>引数を受け取り、次のCodeGearに継続する <ul> <li><code>right_fork->checkAndSet</code>はInterfaceのAPI呼び出し</li> </ul> </li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_rfork</span><span class="hljs-params">(struct PhilsImpl* phils, __code next(...))</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">right_fork</span> =</span> phils->Rightfork; <span class="hljs-keyword">goto</span> right_fork->checkAndSet(<span class="hljs-number">-1</span>, phils->self, pickup_lfork, pickup_rfork); } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-paginate="true" data-marpit-pagination="15" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Interface</h1> <ul> <li>GearsOSのモジュール化の仕組み</li> <li>APIとなるCodeGear とその操作に用いる DataGear の集合を表現する</li> <li>JavaのInteface、Haskellの型クラスに相当する</li> <li><code>goto interfaceName->method()</code>のようにAPIを呼び出す <ul> <li>CbCのgoto文なので引数を渡すことも可能</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-paginate="true" data-marpit-pagination="16" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルでのInterface(ノーマルレベル)</h1> <ul> <li>実装したいInterfaceのCodeGearの名前と引数を列挙する</li> </ul> <pre><code class="language-c"><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">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Stack</span><</span>>{ <span class="hljs-function">__code <span class="hljs-title">whenEmpty</span><span class="hljs-params">(...)</span></span>; <span class="hljs-function">__code <span class="hljs-title">clear</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>,__code next(...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">push</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>,Type* data, __code next(...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">pop</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>, __code next(Type* data, ...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">pop2</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>, __code next(Type* data, Type* data1, ...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">isEmpty</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>, __code next(...), __code whenEmpty(...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">get</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>, __code next(Type* data, ...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">get2</span><span class="hljs-params">(Impl* <span class="hljs-built_in">stack</span>, __code next(Type* data, Type* data1, ...))</span></span>; <span class="hljs-function">__code <span class="hljs-title">next</span><span class="hljs-params">(...)</span></span>; } Stack; </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-paginate="true" data-marpit-pagination="17" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Interfaceの実装(ノーマルレベル)</h1> <ul> <li>実装したいInterfaceで定義されたAPIを実装する <ul> <li>従来はすべて手書きしていた</li> </ul> </li> </ul> <pre><code class="language-c"><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-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"../../../context.h"</span></span> <span class="hljs-meta">#interface <span class="hljs-meta-string">"Stack.h"</span></span> ... <span class="hljs-function">__code <span class="hljs-title">push</span><span class="hljs-params">(struct SingleLinkedStack* <span class="hljs-built_in">stack</span>, <span class="hljs-keyword">union</span> Data* data, __code next(...))</span> </span>{ Element* element = <span class="hljs-keyword">new</span> Element(); element->next = <span class="hljs-built_in">stack</span>->top; element->data = data; <span class="hljs-built_in">stack</span>->top = element; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">next</span><span class="hljs-params">(...)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-paginate="true" data-marpit-pagination="18" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>InterfaceのAPI呼び出し(ノーマルレベル)</h1> <ul> <li><code>goto interfaceName->method()</code>のようにAPIを呼び出す</li> <li><code>StackTest</code> interfaceの<code>insertTest1</code>をAPI呼び出し <ul> <li>引数で<code>stack</code>、<code>shutdown</code>を渡している</li> <li><code>StackTest</code>の実装は<code>createStackTestImpl3</code>で作っている</li> </ul> </li> </ul> <pre><code class="language-c"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>Stack* <span class="hljs-built_in">stack</span> = createSingleLinkedStack(context); StackTest* stackTest = createStackTestImpl3(context); <span class="hljs-keyword">goto</span> stackTest->insertTest1(<span class="hljs-built_in">stack</span>, shutdown); </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-paginate="true" data-marpit-pagination="19" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>par goto</h1> <ul> <li>GearsOSの並行呼び出し構文</li> <li>通常のgoto文の様に<code>par goto</code>と書くと、並列実行される</li> </ul> <pre><code class="language-c"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap> Phils* phils0 = createPhilsImpl(context,<span class="hljs-number">0</span>,fork0,fork1); Phils* phils1 = createPhilsImpl(context,<span class="hljs-number">1</span>,fork1,fork2); Phils* phils2 = createPhilsImpl(context,<span class="hljs-number">2</span>,fork2,fork3); Phils* phils3 = createPhilsImpl(context,<span class="hljs-number">3</span>,fork3,fork4); Phils* phils4 = createPhilsImpl(context,<span class="hljs-number">4</span>,fork4,fork0); par <span class="hljs-keyword">goto</span> phils0->thinking(exit_code); par <span class="hljs-keyword">goto</span> phils1->thinking(exit_code); par <span class="hljs-keyword">goto</span> phils2->thinking(exit_code); par <span class="hljs-keyword">goto</span> phils3->thinking(exit_code); par <span class="hljs-keyword">goto</span> phils4->thinking(exit_code); </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-paginate="true" data-marpit-pagination="20" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルのまとめ</h1> <ul> <li><code>goto next</code>などで次の継続に飛ぶ <ul> <li>継続に値を渡すことも可能</li> </ul> </li> <li>ノーマルレベルのGearsOSのコードにはInterfaceがある <ul> <li>実装を隠蔽、抽象化できる</li> <li>呼び出す際は<code>goto interface->method()</code>を使う</li> </ul> </li> <li><code>par goto</code>で並列実行</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-paginate="true" data-marpit-pagination="21" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのメタレベルの計算とMetaDataGear</h1> <ul> <li>GearsOSのメタレベルの計算は、GearsOSの基本構造と関わりが深い</li> <li>GearsOSの基本構造はメタなCodeGear/DataGearで表現される</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-paginate="true" data-marpit-pagination="22" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>MetaDataGear</h1> <ul> <li>ノーマルレベルのCodeGearの前後でMetaCodeGearが実行される <ul> <li>MetaCodeGear参照するDataGearのことをMetaDataGearと呼ぶ<br /> <img src="./metacg.svg" alt="h:220 w:800" style="width:800px;height:220px;" /></li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-paginate="true" data-marpit-pagination="23" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのシステム構成</h1> <ul> <li>MetaDataGearであるContext, TaskManager, Workerによって構成</li> </ul> <p><img src="./gears_structure.svg" alt="" /></p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-paginate="true" data-marpit-pagination="24" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Context</h1> <ul> <li>従来のOSのプロセスに相当するMetaDataGear</li> <li>GearsOSでのプログラム実行に必要な情報を持っている <ul> <li>DataGearの型定義</li> <li>CodeGearの名前とStubCodeGearへの対応</li> <li>goto時に引数を書き込むDataGearごとの場所</li> <li>DataGearを管理するヒープ情報</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-paginate="true" data-marpit-pagination="25" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Context</h1> <ul> <li>GearsOSでcontextを触るのはメタ計算部分だけ <ul> <li>ノーマルレベルではcontextに触れない</li> </ul> </li> <li>従来は手書きでcontext.hの中で定義</li> <li>Context自体は構造体で定義されている<br /> <img src="./context.svg" alt="w:532 h:10cm" style="width:532px;height:10cm;" /></li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-paginate="true" data-marpit-pagination="26" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタレベルでのDataGearの管理</h1> <ul> <li>メタレベルではDataGearを纏めて管理する必要がある</li> <li>すべてのDataGearはCの共用体を使って定義される <ul> <li><code>union Data</code>型</li> </ul> </li> <li><code>union Data</code>はすべてのDataGearにキャストすることが可能 <ul> <li>Contextには<code>union Data</code>としてDataGearを保存する</li> </ul> </li> <li>メタレベルの計算では必ずこの<code>union Data</code>が利用される</li> </ul> <pre><code class="language-c"><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">union</span> <span class="hljs-title">Data</span> {</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Stack</span> {</span> ... } Stack; <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">SingleLinkedStack</span> {</span> ... } SingleLinkedStack; <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Context</span> <span class="hljs-title">Context</span>;</span> ... } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-paginate="true" data-marpit-pagination="27" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>union Dataの定義</h1> <ul> <li>union Data型はcontext.hに定義されている</li> <li>計算で使うすべてのDataGearの構造体の定義を列挙する <ul> <li>従来は手書きですべて記述</li> <li>Intefaceの定義を書き、CbCを書き、context.hに追記...</li> </ul> </li> <li>手書きで生成していたので、いくつかの問題があった <ul> <li>整理しないと計算に使わないDataGearの定義が残る</li> <li>Interfaceの定義ファイルと食い違うケースがある</li> <li>DataGearの数が増えると手書きするのが煩雑</li> </ul> </li> <li>すべてのメタレベルの計算の元となる重要なデータ <ul> <li>手書きの場合ミスが発生する可能性が高い</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="28" data-paginate="true" data-marpit-pagination="28" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタレベルに変換されたGearsOSの実装</h1> <ul> <li> <p>ノーマルレベルのCodeGearの継続は、contextとCodeGearの番号のみ指定する</p> <ul> <li>次の継続を番号で指定する</li> <li>次の継続への引数も値をcontextに書き込むように変更される</li> </ul> </li> <li> <p>CodeGearの継続は直接行かず、MetaCodeGearを経由して継続する</p> <ul> <li>呼び出したいCodeGearはMetaCodeGearが番号から取り出す</li> <li>アドレスを直接使うのはメタ計算のみ</li> <li>各CodeGearはContextのみ持ち歩き、入力はStubCodeGearから与えられる</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="29" data-paginate="true" data-marpit-pagination="29" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>CodeGear、DataGearの番号</h1> <ul> <li>Perlで変換するとCodeGear/DataGear番号の形に抽象化される <ul> <li>番号から具体的なCodeGear/DataGearを取り出すのはメタレベル <ul> <li><code>goto meta</code>でcontextからCodeGearの取り出し</li> <li>StubCodeGearでcotnextからDataGearの取り出し</li> </ul> </li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="30" data-paginate="true" data-marpit-pagination="30" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>CodeGearの番号</h1> <ul> <li>ビルドするCbCファイルをPerlで解析し、<code>__code</code>を数え上げる <ul> <li>連番でenumを生成する</li> </ul> </li> <li>Contextの中にCodeGearの配列がある <ul> <li>StubCodeGearへの参照が含まれている</li> </ul> </li> </ul> <pre><code class="language-c"><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">enum</span> <span class="hljs-title">Code</span> {</span> C_checkAndSetAtomicReference, C_clearSingleLinkedStack, C_clearSynchronizedQueue, C_createTask, C_decrementTaskCountTaskManagerImpl, C_exit_code, C_get2SingleLinkedStack, ... }; </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="31" data-paginate="true" data-marpit-pagination="31" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>DataGearの番号</h1> <ul> <li>union Dataで定義されている構造体一覧からPerlで生成される <ul> <li>context.hの内容に依存する</li> </ul> </li> </ul> <pre><code class="language-c"><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">enum</span> <span class="hljs-title">DataType</span> {</span> D_Code, D_Atomic, D_AtomicReference, D_CPUWorker, D_Context, D_Element, ... }; </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="32" data-paginate="true" data-marpit-pagination="32" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>StubCodeGear</h1> <ul> <li>DataGearにアクセスするにはContextから番号を指定して行う</li> <li>メタレベルのCodeGearは引数はContextのみになっている <ul> <li>CodeGearの引数に指定していたものは、ContextからMetaCodeGearで取り出す必要がある</li> </ul> </li> <li>StubCodeGearはCodeGearの直前に実行されて、DataGearをContextから取得する</li> </ul> <p><img src="./contextContinuation.svg" alt="w:540 h:400" style="width:540px;height:400px;" /></p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="33" data-paginate="true" data-marpit-pagination="33" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>ノーマルレベルのpopの確認</h1> <pre><code class="language-c"><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">__code <span class="hljs-title">pop</span><span class="hljs-params">(struct SingleLinkedStack* <span class="hljs-built_in">stack</span>, __code next(<span class="hljs-keyword">union</span> Data* data, ...))</span> </span>{ <span class="hljs-keyword">if</span> (<span class="hljs-built_in">stack</span>->top) { data = <span class="hljs-built_in">stack</span>->top->data; <span class="hljs-built_in">stack</span>->top = <span class="hljs-built_in">stack</span>->top->next; } <span class="hljs-keyword">else</span> { data = <span class="hljs-literal">NULL</span>; } <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">next</span><span class="hljs-params">(data, ...)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="34" data-paginate="true" data-marpit-pagination="34" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタレベルに変換されたGearsOSの実装</h1> <ul> <li>継続先は<code>goto meta</code>に変更されている <ul> <li>継続先は<code>next</code>に代入されている番号で決まる</li> </ul> </li> <li>出力の<code>data</code>は引数でもらった場所に書き込まれる <ul> <li>この引数はStubCodeGearで渡される</li> </ul> </li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">popSingleLinkedStack</span><span class="hljs-params">(struct Context *context,struct SingleLinkedStack* <span class="hljs-built_in">stack</span>, <span class="hljs-keyword">enum</span> Code next,<span class="hljs-keyword">union</span> Data **O_data)</span> </span>{ Data* data __attribute__((unused)) = *O_data; <span class="hljs-keyword">if</span> (<span class="hljs-built_in">stack</span>->top) { data = <span class="hljs-built_in">stack</span>->top->data; <span class="hljs-built_in">stack</span>->top = <span class="hljs-built_in">stack</span>->top->next; } <span class="hljs-keyword">else</span> { data = <span class="hljs-literal">NULL</span>; } *O_data = data; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">meta</span><span class="hljs-params">(context, next)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="35" data-paginate="true" data-marpit-pagination="35" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>popのStubCodeGear</h1> <ul> <li>CodeGearで必要なデータをContextから取り出す操作 <ul> <li>実行したいCodeGearの直前に実行される</li> </ul> </li> <li>この場合はContext中のStackの引数格納場所から値を取り出す</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">popSingleLinkedStack_stub</span><span class="hljs-params">(struct Context* context)</span> </span>{ SingleLinkedStack* <span class="hljs-built_in">stack</span> = (SingleLinkedStack*)GearImpl(context, Stack, <span class="hljs-built_in">stack</span>); <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Code</span> <span class="hljs-title">next</span> =</span> Gearef(context, Stack)->next; Data** O_data = &Gearef(context, Stack)->data; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">popSingleLinkedStack</span><span class="hljs-params">(context, <span class="hljs-built_in">stack</span>, next, O_data)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="36" data-paginate="true" data-marpit-pagination="36" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタに変換されたGearsOSの実装</h1> <ul> <li>直接checkAndSetに行かずにmetaに飛ぶ</li> <li>もとのコードは<code>goto right_fork->checkAndSet()</code>なので、Interfaceを使った継続 <ul> <li>context内の継続先のInterfaceの引数格納用の配列に書き込まれる</li> <li><code>right_fork->checkAndSet</code>には数値が入ってる</li> </ul> </li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_rforkPhilsImpl</span><span class="hljs-params">(struct Context *context,struct PhilsImpl* phils, <span class="hljs-keyword">enum</span> Code next)</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">right_fork</span> =</span> phils->Rightfork; Gearef(context, AtomicT_int)->atomicT_int = (<span class="hljs-keyword">union</span> Data*) right_fork; Gearef(context, AtomicT_int)->oldData = <span class="hljs-number">-1</span>; Gearef(context, AtomicT_int)->newData = phils->self; Gearef(context, AtomicT_int)->next = C_pickup_lforkPhilsImpl; (cGearefontext, AtomicT_int)->fail = C_pickup_rforkPhilsImpl; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">meta</span><span class="hljs-params">(context, right_fork->checkAndSet)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="37" data-paginate="true" data-marpit-pagination="37" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタに変換されたGearsOSの実装</h1> <ul> <li>変換前</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_rfork</span><span class="hljs-params">(struct PhilsImpl* phils, __code next(...))</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">right_fork</span> =</span> phils->Rightfork; <span class="hljs-keyword">goto</span> right_fork->checkAndSet(<span class="hljs-number">-1</span>, phils->self, pickup_lfork, pickup_rfork); } </span></span></foreignObject></svg></code></pre> <ul> <li>変換後</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_rforkPhilsImpl</span><span class="hljs-params">(struct Context *context,struct PhilsImpl* phils, <span class="hljs-keyword">enum</span> Code next)</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">right_fork</span> =</span> phils->Rightfork; Gearef(context, AtomicT_int)->atomicT_int = (<span class="hljs-keyword">union</span> Data*) right_fork; Gearef(context, AtomicT_int)->oldData = <span class="hljs-number">-1</span>; Gearef(context, AtomicT_int)->newData = phils->self; Gearef(context, AtomicT_int)->next = C_pickup_lforkPhilsImpl; (cGearefontext, AtomicT_int)->fail = C_pickup_rforkPhilsImpl; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">meta</span><span class="hljs-params">(context, right_fork->checkAndSet)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="38" data-paginate="true" data-marpit-pagination="38" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>データを取り出すStubCodeGear</h1> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_rforkPhilsImpl_stub</span><span class="hljs-params">(struct Context* context)</span> </span>{ PhilsImpl* phils = (PhilsImpl*)GearImpl(context, Phils, phils); <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Code</span> <span class="hljs-title">next</span> =</span> Gearef(context, Phils)->next; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">pickup_rforkPhilsImpl</span><span class="hljs-params">(context, phils, next)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="39" data-paginate="true" data-marpit-pagination="39" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのビルドシステム</h1> <ul> <li>Perlスクリプトはファイルの変換・生成を行う <ul> <li>メタ計算の変換・自動生成も行う</li> </ul> </li> <li>メタ計算で必要なファイル、データ構造も生成する <ul> <li>CodeGear/DataGearの番号など</li> </ul> </li> </ul> <p><img src="./geasflow1.svg" alt="w:632 h:10cm" style="width:632px;height:10cm;" /></p> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="40" data-paginate="true" data-marpit-pagination="40" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Perlトランスパイラが生成するファイル</h1> <ul> <li>context.hの中身をもとに生成するファイルが多い <ul> <li>このファイルで定義した内容をもとにメタレベルの計算をするので重要</li> </ul> </li> </ul> <table> <thead> <tr> <th>ファイル名</th> <th>内容</th> <th>元にするファイル</th> </tr> </thead> <tbody> <tr> <td>*.c</td> <td>メタレベルに変換したGearsOSのコード</td> <td>*.cbc</td> </tr> <tr> <td>enumData.h</td> <td>DataGearの番号を管理するenum</td> <td>context.h</td> </tr> <tr> <td>enumCode.h</td> <td>CodeGearの番号を管理するenum</td> <td>変換された.cファイル</td> </tr> <tr> <td>extern.h</td> <td>CodeGearのextern一覧</td> <td>変換された.cファイル</td> </tr> <tr> <td>project-context.c</td> <td>Contextの初期化ルーチンなどのCodeGear</td> <td>context.h</td> </tr> <tr> <td>typedefData.h</td> <td>DataGearのtypef一覧</td> <td>context.h</td> </tr> <tr> <td>dataGearInit.c</td> <td>DataGearのアロケート処理</td> <td>context.h</td> </tr> </tbody> </table> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="41" data-paginate="true" data-marpit-pagination="41" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSのメタレベルについてのまとめ</h1> <ul> <li>ノーマルレベルで書いたCodeGearにはContextの操作が付け加わる</li> <li>継続への書き込み、CodeGearの値の受け取りはContext経由で行われる <ul> <li>値の受け取りはStubCodeGearが行う</li> <li>PerlトランスパイラでMetaCodeGearが生成される</li> </ul> </li> <li>メタレベルへの変換はビルド時にPerlトランスパイラによって行われる</li> <li>メタレベルの情報はPerlトランスパイラが生成するファイがル重要 <ul> <li>DataGearの扱いはcontext.hに定義したunion Dataに依存する</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="42" data-paginate="true" data-marpit-pagination="42" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Perlを中心としたフレームワークによるメタ計算の生成</h1> <ul> <li>GearsOSの例題を作製する場合も、コピペや手書きが多発していた <ul> <li>フレームワークに実装したAPIを使って自動生成に変更したい</li> </ul> </li> <li>Interfaceの機能充実も、 メタ計算の生成もCbCで行うのは難しい <ul> <li>Perlを中心としたフレームワークを活用したい</li> </ul> </li> <li>コード変換(トランスパイル)を行うために必要な環境の整備もする必要がある</li> <li>Perlを中心としたトランスパイルシステムの整備、拡張を行った <ul> <li>GearsOSのメタ計算の生成がより柔軟かつ高い信頼性で可能となった</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="43" data-paginate="true" data-marpit-pagination="43" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>主なGearsOSに導入された新機能</h1> <ul> <li>Interfaceシステムの強化</li> <li>手書きからの解放</li> <li>MetaCodeGearの入れ替え機能の追加</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="44" data-paginate="true" data-marpit-pagination="44" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Interfaceシステムの強化</h1> <ul> <li>Interface構文の簡素化 <ul> <li>より簡潔に明確に記述できるように定義した。</li> </ul> </li> <li>Interfaceの実装の型の導入 <ul> <li>GearsOSでの型定義の方法に一貫性が生まれた</li> </ul> </li> <li>InterfaceのParserの実装</li> <li>Interfaceの引数の確認</li> <li>Interfaceで未定義のAPIの検知</li> <li>InterfaceにないAPIの呼び出しの検知 <ul> <li>他の言語のいわゆるInterfaceの機能が強化</li> <li>コード変換前にPerlレベルでエラーを発生させた</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="45" data-paginate="true" data-marpit-pagination="45" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>手書きからの解放</h1> <ul> <li>Interfaceの雛形ファイルの作製スクリプトの導入</li> <li>別のInterfaceからの出力を取得するStubの自動生成</li> <li>実装のCodeGear名からメタ情報の切り離し <ul> <li>メタな型情報はビルド時に付与される</li> </ul> </li> <li>DataGearの型集合ファイルであるcontext.hの自動生成</li> <li>GearsOSの初期化ルーチンの自動生成</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="46" data-paginate="true" data-marpit-pagination="46" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>GearsOSの新機能</h1> <ul> <li><strong>自由なMetaCodeGearの作製、継続の入れ替え機能</strong></li> <li>Perlトランスパイラの変換ルーチンのデバッグ機能の追加 <ul> <li>トランスパイラそのもののデバッグが困難であった</li> </ul> </li> <li>ジェネリクスのサポート</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="47" data-paginate="true" data-marpit-pagination="47" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Interfaceの改良</h1> <ul> <li>従来のInterfaceにまつわるPerlのフレームワークを改良した <ul> <li>CbCの変換後のコードでなく、Perlレベルでエラー検知可能になった</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="48" data-paginate="true" data-marpit-pagination="48" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Implementの型定義ファイルの導入</h1> <ul> <li>Interfaceは型定義ファイルがあったが、実装側はなかった</li> <li>context.h上のunion Dataの定義に型定義を書いていた <ul> <li>メタな構造体に直した実装の型を手書き</li> <li>型定義の一貫性がない(Intefaceはファイルが導入)</li> <li>これはメタ情報なので手で書きたくない</li> </ul> </li> <li>実装側にも型定義ファイルを導入して一貫性を持たせたい <ul> <li>PerlトランスパイラフレームワークでInterface/Implの定義ファイルを纏めて扱える</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="49" data-paginate="true" data-marpit-pagination="49" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Implementの型定義</h1> <ul> <li>基本はInterfaceと同じシンタックス <ul> <li>どのInterfaceを実装しているかを<code>Impl</code>の後ろに書く</li> </ul> </li> <li>Implの場合はフィールド変数を定義できる</li> <li><code>実装名.h</code>の命名規則 (<code>PhilsImp.h</code> )</li> </ul> <pre><code class="language-c"><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">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">PhilsImpl</span> <</span>> impl Phils { <span class="hljs-keyword">int</span> self; <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">Leftfork</span>;</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">Rightfork</span>;</span> <span class="hljs-function">__code <span class="hljs-title">next</span><span class="hljs-params">(...)</span></span>; } PhilsImpl; </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="50" data-paginate="true" data-marpit-pagination="50" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Interfaceの実装時の型名の省略</h1> <ul> <li>APIのCodeGearには、トランスパイル時に具体的な型が名前につけられる</li> </ul> <h3>トランスパイル前</h3> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_lfork</span><span class="hljs-params">(struct PhilsImpl* phils, __code next(...))</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">left_fork</span> =</span> phils->Leftfork; <span class="hljs-keyword">goto</span> left_fork->checkAndSet(<span class="hljs-number">-1</span>, phils->self, pickup_rfork, eating); } </span></span></foreignObject></svg></code></pre> <h3>トランスパイル後</h3> <pre><code class="language-c"><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">__code <span class="hljs-title">pickup_lforkPhilsImpl</span><span class="hljs-params">(struct Context *context,struct PhilsImpl* phils, <span class="hljs-keyword">enum</span> Code next)</span> </span>{ <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">AtomicT_int</span>* <span class="hljs-title">left_fork</span> =</span> phils->Leftfork; Gearef(context, AtomicT_int)->atomicT_int = (<span class="hljs-keyword">union</span> Data*) left_fork; ... Gearef(context, AtomicT_int)->next = C_pickup_rforkPhilsImpl; Gearef(context, AtomicT_int)->fail = C_eatingPhilsImpl; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">meta</span><span class="hljs-params">(context, left_fork->checkAndSet)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="51" data-paginate="true" data-marpit-pagination="51" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>PerlトランスパイラでのInterfaceのエラー生成</h1> <ul> <li>CbCコンパイラがコンパイルする前にトランスパイラで検知可能になった</li> </ul> <h2>実装をし忘れているAPIがあった場合のエラー終了</h2> <ul> <li>PerlトランスパイラでのInterfaceのエラー生成 <ul> <li>CbCコンパイラが動く前にエラーを検知</li> </ul> </li> </ul> <pre><code><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>[ 33%] Generating c/examples/DPP2/PhilsImpl.c [ERROR] Not define eating at examples/DPP2/PhilsImpl.cbc make[3]: *** [CMakeFiles/DPP2.dir/build.make:101: c/examples/DPP2/PhilsImpl.c] Error 25 make[2]: *** [CMakeFiles/Makefile2:442: CMakeFiles/DPP2.dir/all] Error 2 make[1]: *** [CMakeFiles/Makefile2:450: CMakeFiles/DPP2.dir/rule] Error 2 make: *** [Makefile:293: DPP2] Error 2 </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="52" data-paginate="true" data-marpit-pagination="52" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>手書きからの解放</h1> <ul> <li>従来はメタレベルの計算に関係する処理・ファイルを手書きするケースが多々あった <ul> <li>手書きではなく型定義ファイルからのファイル生成</li> <li>トランスパイル時にコードの解析を行いメタ計算を自動生成</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="53" data-paginate="true" data-marpit-pagination="53" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>今回の修論での変更点/追加点の一覧</h1> <table> <thead> <tr> <th>項目</th> <th>従来</th> <th>今回の修論</th> </tr> </thead> <tbody> <tr> <td>実装の型ファイル</td> <td>無し</td> <td>新たに導入</td> </tr> <tr> <td>union Dataの定義</td> <td>手書き</td> <td>自動生成</td> </tr> <tr> <td>実装のCodeGearの型名</td> <td>手書き</td> <td>自動生成</td> </tr> <tr> <td>実装のCbCファイル</td> <td>手書き</td> <td>雛形を自動生成</td> </tr> <tr> <td>別のInterfaceの出力を取得するStub</td> <td>手書き</td> <td>自動生成</td> </tr> <tr> <td>Interfaceの未実装の場合の警告</td> <td>無し</td> <td>新たに導入</td> </tr> <tr> <td>Interfaceのparser</td> <td>スクリプトに埋め込み</td> <td>モジュール化</td> </tr> <tr> <td>MetaCodeGearの差し替え処理</td> <td>手書き</td> <td>meta.pmによって自動化</td> </tr> <tr> <td>par gotoのInterface呼び出し</td> <td>非対応</td> <td>対応</td> </tr> </tbody> </table> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="54" data-paginate="true" data-marpit-pagination="54" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Context定義ファイルの自動生成</h1> <ul> <li>ContextはすべてのDataGearの型情報をunion Dataとして持つ必要がある <ul> <li>すべてのDataGearの定義をunion Dataの定義内に書く</li> </ul> </li> <li>これは今まで手書きで作製していた <ul> <li>Interfaceの型定義ファイルを導入したので、自動生成が可能になった</li> </ul> </li> <li>ビルド時に使用しているDataGearを回収し、 context.hを作製する</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="55" data-paginate="true" data-marpit-pagination="55" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>出力があるIntefaceのAPIの問題</h1> <h2>Stackから値を2つ取得するpop2 APIの定義の一部</h2> <ul> <li>値を2つとってくるのがGearsOSだと煩雑なので定義したAPI <ul> <li>継続先に値を2つ書き込む</li> </ul> </li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pop2</span><span class="hljs-params">(struct SingleLinkedStack* <span class="hljs-built_in">stack</span>, __code next(<span class="hljs-keyword">union</span> Data* data, <span class="hljs-keyword">union</span> Data* data1, ...))</span> </span>{ <span class="hljs-keyword">if</span> (<span class="hljs-built_in">stack</span>->top) { data = <span class="hljs-built_in">stack</span>->top->data; <span class="hljs-built_in">stack</span>->top = <span class="hljs-built_in">stack</span>->top->next; } <span class="hljs-keyword">else</span> { data = <span class="hljs-literal">NULL</span>; } <span class="hljs-keyword">if</span> (<span class="hljs-built_in">stack</span>->top) { data1 = <span class="hljs-built_in">stack</span>->top->data; <span class="hljs-built_in">stack</span>->top = <span class="hljs-built_in">stack</span>->top->next; } <span class="hljs-keyword">else</span> { data1 = <span class="hljs-literal">NULL</span>; } <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">next</span><span class="hljs-params">(data, data1, ...)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="56" data-paginate="true" data-marpit-pagination="56" data-marpit-pagination-total="64" style="--paginate:true;"> <h2>pop2 APIの呼び出し</h2> <ul> <li>pop2を呼び出して、Stackの中身を2つ<code>pop2Test1</code>で受け取る</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pop2Test</span><span class="hljs-params">(struct StackTestImpl3* stackTest, struct Stack* <span class="hljs-built_in">stack</span>, __code next(...))</span> </span>{ <span class="hljs-keyword">goto</span> <span class="hljs-built_in">stack</span>->pop2(pop2Test1); } </span></span></foreignObject></svg></code></pre> <h2>pop2 APIからデータの受け取り(ノーマルレベル)</h2> <ul> <li>Stackからデータを2つ受け取る継続</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">pop2Test1</span><span class="hljs-params">(struct StackTestImpl3* stackTest, <span class="hljs-keyword">union</span> Data* data, <span class="hljs-keyword">union</span> Data* data1, struct Stack* <span class="hljs-built_in">stack</span>, __code next(...))</span> </span>{ String* str = (String*)data; String* str2 = (String*)data1; <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, str->size); <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d\n"</span>, str2->size); <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">next</span><span class="hljs-params">(...)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="57" data-paginate="true" data-marpit-pagination="57" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>出力があるIntefaceのAPIの問題</h1> <ul> <li>従来は別のInterfaceからの出力を受け取るCodeGearのStubは手で書かないといけなかった <ul> <li>Contextにあるデータの場所がずれているので、StubCodeGearがデータをとってきてくれない <ul> <li>Interfaceが値をとるContextの場所</li> <li>Stackがdataを書き込むContextの場所</li> </ul> </li> </ul> </li> <li>Perlトランスパイラで呼び出しているAPIのInterfaceを解析し、Contextの場所を明確に指定するStubCodeGearを自動で作製するようにした</li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="58" data-paginate="true" data-marpit-pagination="58" data-marpit-pagination-total="64" style="--paginate:true;"> <h2>元のStub</h2> <pre><code class="language-c"><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">__code <span class="hljs-title">pop2Test1StackTestImpl3_stub</span><span class="hljs-params">(struct Context* context)</span> </span>{ StackTestImpl3* stackTest = (StackTestImpl3*)GearImpl(context, StackTest, stackTest); Data* data = Gearef(context, StackTest)->data; Data* data1 = Gearef(context, StackTest)->data1; Stack* <span class="hljs-built_in">stack</span> = Gearef(context, StackTest)-><span class="hljs-built_in">stack</span>; <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Code</span> <span class="hljs-title">next</span> =</span> Gearef(context, StackTest)->next; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">pop2Test1StackTestImpl3</span><span class="hljs-params">(context, stackTest, data, data1, <span class="hljs-built_in">stack</span>, next)</span></span>; } </span></span></foreignObject></svg></code></pre> <h2>自動生成したStub(従来は手書き)</h2> <pre><code class="language-c"><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">__code <span class="hljs-title">pop2Test1StackTestImpl3_1_stub</span><span class="hljs-params">(struct Context* context)</span> </span>{ StackTestImpl3* stackTest = (StackTestImpl3*)GearImpl(context, StackTest, stackTest); Data* data = Gearef(context, Stack)->data; Data* data1 = Gearef(context, Stack)->data1; Stack* <span class="hljs-built_in">stack</span> = Gearef(context, StackTest)-><span class="hljs-built_in">stack</span>; <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Code</span> <span class="hljs-title">next</span> =</span> Gearef(context, StackTest)->next; <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">pop2Test1StackTestImpl3</span><span class="hljs-params">(context, stackTest, data, data1, <span class="hljs-built_in">stack</span>, next)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="59" data-paginate="true" data-marpit-pagination="59" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>メタ計算の切り替えAPI</h1> <ul> <li>CodeGearが継続するMetaCodeGearを自由に選択できるPerlモジュールを導入した <ul> <li>従来はデフォルトで設定されるMetaCodeGearにしか継続しなかった</li> <li>Perlモジュールを書くことで特定のCodeGearの継続先を変更可能にした</li> </ul> </li> <li>AspectJのポイントカットが類似機能<br /> <img src="./metapm.svg" alt="w:932 h:10cm" style="width:932px;height:10cm;" /></li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="60" data-paginate="true" data-marpit-pagination="60" data-marpit-pagination-total="64" style="--paginate:true;"> <h1><a href="http://meta.pm">meta.pm</a></h1> <ul> <li><code>replaceMeta</code>関数に置換対象を登録 <ul> <li><code>qr//</code>に正規表現リテラルで置換対象のCodeGearの名前を指定</li> <li><code>=></code>の先に対応するgoto文の生成関数を指定する</li> </ul> </li> </ul> <pre><code class="language-perl"><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">package</span> meta; <span class="hljs-function"><span class="hljs-keyword">sub</span> <span class="hljs-title">replaceMeta</span> </span>{ <span class="hljs-keyword">return</span> ( [<span class="hljs-regexp">qr/PhilsImpl/</span> => \&generateMcMeta], ); } <span class="hljs-function"><span class="hljs-keyword">sub</span> <span class="hljs-title">generateMcMeta</span> </span>{ <span class="hljs-keyword">my</span> ($context, $next) = @_; <span class="hljs-keyword">return</span> <span class="hljs-string">"goto mcMeta($context, $next);"</span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="61" data-paginate="true" data-marpit-pagination="61" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>Perlトランスパイルで生成されたメタ部分の比較</h1> <h2>meta.pm導入前</h2> <ul> <li>通常の<code>goto meta</code></li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">thinkingPhilsImpl</span><span class="hljs-params">(struct Context *context,struct PhilsImpl* phils, struct Fork* fork, <span class="hljs-keyword">enum</span> Code next)</span> </span>{ <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d: thinking\n"</span>, phils->self); <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">meta</span><span class="hljs-params">(context, C_pickup_lforkPhilsImpl)</span></span>; } </span></span></foreignObject></svg></code></pre> <h2>meta.pm導入後</h2> <ul> <li>モデル検査用のMetaCodeGear<code>mcMeta</code>に<code>goto</code>する</li> </ul> <pre><code class="language-c"><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">__code <span class="hljs-title">thinkingPhilsImpl</span><span class="hljs-params">(struct Context *context,struct PhilsImpl* phils, struct Fork* fork, <span class="hljs-keyword">enum</span> Code next)</span> </span>{ <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d: thinking\n"</span>, phils->self); <span class="hljs-function"><span class="hljs-keyword">goto</span> <span class="hljs-title">mcMeta</span><span class="hljs-params">(context, C_pickup_lforkPhilsImpl)</span></span>; } </span></span></foreignObject></svg></code></pre> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="62" data-paginate="true" data-marpit-pagination="62" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>今後の課題</h1> <ul> <li>Perlトランスパイラのリファクタリング・GearsOSのビルド方法の見直し <ul> <li>機能が充実したが複雑度が全体的に増してしまった</li> </ul> </li> <li>PerlトランスパイラのGearsOS本体への組み込み <ul> <li>Perlトランスパイラが行っている処理はリンカ、ローダーに近い</li> <li>OSが機能としてサポートしていてほしい</li> <li>GearsOS自身で記述したい</li> </ul> </li> <li>xv6への組み込み <ul> <li>GearsOSを既存のUNIXの置き換えとして実行したい</li> </ul> </li> <li>ノーマルレベルの記述の純粋関数化、別の言語での定義 <ul> <li>CbC/Cベースの記述ではノーマルレベルの記述に限界がある</li> <li>Perlトランスパイラの機能をさらに拡張すると、PerlでCbCコンパイラを実装することに近くなってしまう</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="63" data-paginate="true" data-marpit-pagination="63" data-marpit-pagination-total="64" style="--paginate:true;"> <h1>まとめ</h1> <ul> <li>Perlトランスパイラのフレームワークの機能を充実させた</li> <li>Interfaceシステムを改良した <ul> <li>型定義ファイルの導入を行った <ul> <li>定義方法に一貫性が出た</li> </ul> </li> <li>Perlトランスパイラで警告を発生させるようになった</li> </ul> </li> <li>従来手書きしていたメタな定義をビルド時に自動的に生成するようにした <ul> <li>煩雑な処理や手で実装することによるバグの混入を回避</li> </ul> </li> <li>MetaCodeGearの制御をユーザー側で行えるようにした <ul> <li>モデル検査をメタ計算として自在に組み込むことが可能となった</li> </ul> </li> </ul> </section> </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="64" data-paginate="true" data-marpit-pagination="64" data-marpit-pagination-total="64" style="--paginate:true;"></section> <script>!function(){"use strict";const t="marpitSVGPolyfill:setZoomFactor,",e=Symbol();let r,o;function n(n){const i="object"==typeof n&&n.target||document,a="object"==typeof n?n.zoom:n;window[e]||(Object.defineProperty(window,e,{configurable:!0,value:!0}),window.addEventListener("message",(({data:e,origin:r})=>{if(r===window.origin)try{if(e&&"string"==typeof e&&e.startsWith(t)){const[,t]=e.split(","),r=Number.parseFloat(t);Number.isNaN(r)||(o=r)}}catch(t){console.error(t)}})));let l=!1;Array.from(i.querySelectorAll("svg[data-marpit-svg]"),(t=>{var e,n,i,s;t.style.transform||(t.style.transform="translateZ(0)");const c=a||o||t.currentScale||1;r!==c&&(r=c,l=c);const d=t.getBoundingClientRect(),{length:u}=t.children;for(let r=0;r<u;r+=1){const o=t.children[r],a=o.getScreenCTM();if(a){const t=null!==(n=null===(e=o.x)||void 0===e?void 0:e.baseVal.value)&&void 0!==n?n:0,r=null!==(s=null===(i=o.y)||void 0===i?void 0:i.baseVal.value)&&void 0!==s?s:0,l=o.firstChild,{style:u}=l;u.transformOrigin||(u.transformOrigin=`${-t}px ${-r}px`),u.transform=`scale(${c}) matrix(${a.a}, ${a.b}, ${a.c}, ${a.d}, ${a.e-d.left}, ${a.f-d.top}) translateZ(0.0001px)`}}})),!1!==l&&Array.from(i.querySelectorAll("iframe"),(({contentWindow:e})=>{null==e||e.postMessage(`${t}${l}`,"null"===window.origin?"*":window.origin)}))}r=1,o=void 0;const i=(t,e,r)=>{if(t.getAttribute(e)!==r)return t.setAttribute(e,r),!0};function a({once:t=!1,target:e=document}={}){const r="Apple Computer, Inc."===navigator.vendor?[n]:[];let o=!t;const a=()=>{for(const t of r)t({target:e});!function(t=document){Array.from(t.querySelectorAll('svg[data-marp-fitting="svg"]'),(t=>{var e;const r=t.firstChild,o=r.firstChild,{scrollWidth:n,scrollHeight:a}=o;let l,s=1;if(t.hasAttribute("data-marp-fitting-code")&&(l=null===(e=t.parentElement)||void 0===e?void 0:e.parentElement),t.hasAttribute("data-marp-fitting-math")&&(l=t.parentElement),l){const t=getComputedStyle(l),e=Math.ceil(l.clientWidth-parseFloat(t.paddingLeft||"0")-parseFloat(t.paddingRight||"0"));e&&(s=e)}const c=Math.max(n,s),d=Math.max(a,1),u=`0 0 ${c} ${d}`;i(r,"width",`${c}`),i(r,"height",`${d}`),i(t,"preserveAspectRatio",getComputedStyle(t).getPropertyValue("--preserve-aspect-ratio")||"xMinYMin meet"),i(t,"viewBox",u)&&t.classList.toggle("__reflow__")}))}(e),o&&window.requestAnimationFrame(a)};return a(),()=>{o=!1}}const l=Symbol(),s=document.currentScript;((t=document)=>{if("undefined"==typeof window)throw new Error("Marp Core's browser script is valid only in browser context.");if(t[l])return t[l];const e=a({target:t}),r=()=>{e(),delete t[l]};Object.defineProperty(t,l,{configurable:!0,value:r})})(s?s.getRootNode():document)}(); </script></foreignObject></svg></div><script>!function(){"use strict";var e=function(e,t){var n,r=1===(e.parent||e).nodeType?e.parent||e:document.querySelector(e.parent||e),s=[].filter.call("string"==typeof e.slides?r.querySelectorAll(e.slides):e.slides||r.children,(function(e){return"SCRIPT"!==e.nodeName})),a={},i=function(e,t){return(t=t||{}).index=s.indexOf(e),t.slide=e,t},o=function(e,t){a[e]=(a[e]||[]).filter((function(e){return e!==t}))},l=function(e,t){return(a[e]||[]).reduce((function(e,n){return e&&!1!==n(t)}),!0)},c=function(e,t){s[e]&&(n&&l("deactivate",i(n,t)),n=s[e],l("activate",i(n,t)))},d=function(e,t){var r=s.indexOf(n)+e;l(e>0?"next":"prev",i(n,t))&&c(r,t)},u={off:o,on:function(e,t){return(a[e]||(a[e]=[])).push(t),o.bind(null,e,t)},fire:l,slide:function(e,t){if(!arguments.length)return s.indexOf(n);l("slide",i(s[e],t))&&c(e,t)},next:d.bind(null,1),prev:d.bind(null,-1),parent:r,slides:s,destroy:function(e){l("destroy",i(n,e)),a={}}};return(t||[]).forEach((function(e){e(u)})),n||c(0),u};function t(e){e.parent.classList.add("bespoke-marp-parent"),e.slides.forEach((e=>e.classList.add("bespoke-marp-slide"))),e.on("activate",(t=>{const n=t.slide,r=!n.classList.contains("bespoke-marp-active");e.slides.forEach((e=>{e.classList.remove("bespoke-marp-active"),e.setAttribute("aria-hidden","true")})),n.classList.add("bespoke-marp-active"),n.removeAttribute("aria-hidden"),r&&(n.classList.add("bespoke-marp-active-ready"),document.body.clientHeight,n.classList.remove("bespoke-marp-active-ready"))}))}function n(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],s=(r,s)=>{t=r,n=s,e.fragments.forEach(((e,t)=>{e.forEach(((e,n)=>{if(null==e)return;const a=t<r||t===r&&n<=s;e.setAttribute("data-bespoke-marp-fragment",a?"active":"inactive"),t===r&&n===s?e.setAttribute("data-bespoke-marp-current-fragment","current"):e.removeAttribute("data-bespoke-marp-current-fragment")}))})),e.fragmentIndex=s;const a={slide:e.slides[r],index:r,fragments:e.fragments[r],fragmentIndex:s};e.fire("fragment",a)};e.on("next",(({fragment:a=!0})=>{if(a){if(r(1))return s(t,n+1),!1;const a=t+1;e.fragments[a]&&s(a,0)}else{const r=e.fragments[t].length;if(n+1<r)return s(t,r-1),!1;const a=e.fragments[t+1];a&&s(t+1,a.length-1)}})),e.on("prev",(({fragment:a=!0})=>{if(r(-1)&&a)return s(t,n-1),!1;const i=t-1;e.fragments[i]&&s(i,e.fragments[i].length-1)})),e.on("slide",(({index:t,fragment:n})=>{let r=0;if(void 0!==n){const s=e.fragments[t];if(s){const{length:e}=s;r=-1===n?e-1:Math.min(Math.max(n,0),e-1)}}s(t,r)})),s(0,0)} /*! * screenfull * v5.0.2 - 2020-02-13 * (c) Sindre Sorhus; MIT License */ var r,s=(function(e){!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,s=n.length,a={};r<s;r++)if((e=n[r])&&e[1]in t){for(r=0;r<e.length;r++)a[n[0][r]]=e[r];return a}return!1}(),s={change:r.fullscreenchange,error:r.fullscreenerror},a={request:function(e){return new Promise(function(n,s){var a=function(){this.off("change",a),n()}.bind(this);this.on("change",a);var i=(e=e||t.documentElement)[r.requestFullscreen]();i instanceof Promise&&i.then(a).catch(s)}.bind(this))},exit:function(){return new Promise(function(e,n){if(this.isFullscreen){var s=function(){this.off("change",s),e()}.bind(this);this.on("change",s);var a=t[r.exitFullscreen]();a instanceof Promise&&a.then(s).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=s[e];r&&t.addEventListener(r,n,!1)},off:function(e,n){var r=s[e];r&&t.removeEventListener(r,n,!1)},raw:r};r?(Object.defineProperties(a,{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=a:window.screenfull=a):n?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()}(r={exports:{}},r.exports),r.exports);function a(e){e.fullscreen=()=>{s.isEnabled&&s.toggle(document.body)},document.addEventListener("keydown",(t=>{70!==t.which&&122!==t.which||t.altKey||t.ctrlKey||t.metaKey||!s.isEnabled||(e.fullscreen(),t.preventDefault())}))}function i(e=2e3){return t=>{let n;function r(){n&&clearTimeout(n),n=setTimeout((()=>{t.parent.classList.add("bespoke-marp-inactive"),t.fire("marp-inactive")}),e),t.parent.classList.contains("bespoke-marp-inactive")&&(t.parent.classList.remove("bespoke-marp-inactive"),t.fire("marp-active"))}document.addEventListener("mousedown",r),document.addEventListener("mousemove",r),document.addEventListener("touchend",r),setTimeout(r,0)}}const o=["AUDIO","BUTTON","INPUT","SELECT","TEXTAREA","VIDEO"];function l(e){e.parent.addEventListener("keydown",(e=>{if(!e.target)return;const t=e.target;(o.includes(t.nodeName)||"true"===t.contentEditable)&&e.stopPropagation()}))}function c(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)}}))}var d;function u({interval:e=200}={}){return t=>{document.addEventListener("keydown",(e=>{if(32===e.which&&e.shiftKey)t.prev();else if(33===e.which||37===e.which||38===e.which)t.prev({fragment:!e.shiftKey});else if(32!==e.which||e.shiftKey)if(34===e.which||39===e.which||40===e.which)t.next({fragment:!e.shiftKey});else if(35===e.which)t.slide(t.slides.length-1,{fragment:-1});else{if(36!==e.which)return;t.slide(0)}else t.next();e.preventDefault()}));let n,r,s=0;t.parent.addEventListener("wheel",(a=>{let i=!1;const o=(e,t)=>{e&&(i=i||function(e,t){return function(e,t){const n=t===d.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}(getComputedStyle(e),t)}(e,t)),(null==e?void 0:e.parentElement)&&o(e.parentElement,t)};if(0!==a.deltaX&&o(a.target,d.X),0!==a.deltaY&&o(a.target,d.Y),i)return;a.preventDefault(),r&&clearTimeout(r),r=setTimeout((()=>{n=0}),e);const l=Date.now()-s<e,c=Math.sqrt(Math.pow(a.deltaX,2)+Math.pow(a.deltaY,2)),u=c<=n;if(n=c,l||u)return;let f;(a.deltaX>0||a.deltaY>0)&&(f="next"),(a.deltaX<0||a.deltaY<0)&&(f="prev"),f&&(t[f](),s=Date.now())}))}}!function(e){e.X="X",e.Y="Y"}(d||(d={}));const f=(...e)=>history.replaceState(...e),m="data-bespoke-view";var p;!function(e){e.Normal="",e.Presenter="presenter",e.Next="next"}(p||(p={}));const h=(e,{protocol:t,host:n,pathname:r,hash:s}=location)=>{const a=e.toString();return`${t}//${n}${r}${a?"?":""}${a}${s}`},g=()=>{switch(document.body.getAttribute(m)){case p.Normal:return p.Normal;case p.Presenter:return p.Presenter;case p.Next:return p.Next;default:throw new Error("View mode is not assigned.")}},v=e=>new URLSearchParams(location.search).get(e),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,h(r,n.location))}catch(e){console.error(e)}},w={available:(()=>{try{return localStorage.setItem("bespoke-marp","bespoke-marp"),localStorage.removeItem("bespoke-marp"),!0}catch(e){return console.warn("Warning: Using localStorage is restricted in the current host so some features may not work."),!1}})(),get:e=>{try{return localStorage.getItem(e)}catch(e){return null}},set:(e,t)=>{try{return localStorage.setItem(e,t),!0}catch(e){return!1}},remove:e=>{try{return localStorage.removeItem(e),!0}catch(e){return!1}}};function y(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 s.isEnabled||n("fullscreen",(e=>e.style.display="none")),w.available||n("presenter",(e=>{e.disabled=!0,e.title="Presenter view is disabled due to restricted localStorage."})),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({fragment:!t.shiftKey});break;case"prev":e.prev({fragment:!t.shiftKey});break;case"fullscreen":"function"==typeof e.fullscreen&&s.isEnabled&&e.fullscreen();break;case"presenter":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:s})=>{n("prev",(e=>e.disabled=0===t&&0===s)),n("next",(n=>n.disabled=t===e.slides.length-1&&s===r.length-1))})),e.on("marp-active",(()=>t.removeAttribute("aria-hidden"))),e.on("marp-inactive",(()=>t.setAttribute("aria-hidden","true"))),s.isEnabled&&s.onchange((()=>n("fullscreen",(e=>e.classList.toggle("exit",s.isEnabled&&s.isFullscreen)))))}}function x(){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 k(){const e=new URLSearchParams(location.search);return e.set("view","presenter"),e.set("sync",this.syncKey),h(e)}var E=["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"];let L=e=>String(e).replace(/[&<>"']/g,(e=>`&${S[e]};`)),S={"&":"amp","<":"lt",">":"gt",'"':"quot","'":"apos"},I="dangerouslySetInnerHTML",P={className:"class",htmlFor:"for"},M={};function N(e,t){let n=[],r="";t=t||{};for(let e=arguments.length;e-- >2;)n.push(arguments[e]);if("function"==typeof e)return t.children=n.reverse(),e(t);if(e){if(r+="<"+e,t)for(let e in t)!1!==t[e]&&null!=t[e]&&e!==I&&(r+=` ${P[e]?P[e]:L(e)}="${L(t[e])}"`);r+=">"}if(-1===E.indexOf(e)){if(t[I])r+=t[I].__html;else for(;n.length;){let e=n.pop();if(e)if(e.pop)for(let t=e.length;t--;)n.push(e[t]);else r+=!0===M[e]?e:L(e)}r+=e?`</${e}>`:""}return M[r]=!0,r}const F=({children:e})=>N(null,null,...e),$="bespoke-marp-presenter-container",O="bespoke-marp-presenter-next",q="bespoke-marp-presenter-next-container",C="bespoke-marp-presenter-note-container",T="bespoke-marp-presenter-info-container",A="bespoke-marp-presenter-info-page",K="bespoke-marp-presenter-info-page-text",j="bespoke-marp-presenter-info-page-prev",R="bespoke-marp-presenter-info-page-next",U="bespoke-marp-presenter-info-time",D="bespoke-marp-presenter-info-timer";function V(e){const{title:t}=document;document.title="[Presenter view]"+(t?` - ${t}`:"");const n={},r=e=>(n[e]=n[e]||document.querySelector(`.${e}`),n[e]);document.body.appendChild((e=>{const t=document.createElement("div");return t.className=$,t.appendChild(e),t.insertAdjacentHTML("beforeend",N(F,null,N("div",{class:q},N("iframe",{class:O,src:"?view=next"})),N("div",{class:C}),N("div",{class:T},N("div",{class:A},N("button",{class:j,tabindex:"-1",title:"Previous"},"Previous"),N("span",{class:K}),N("button",{class:R,tabindex:"-1",title:"Next"},"Next")),N("time",{class:U,title:"Current time"}),N("div",{class:D})))),t})(e.parent)),(e=>{r(q).addEventListener("click",(()=>e.next()));const t=r(O),n=(s=t,(e,t)=>{var n;return null===(n=s.contentWindow)||void 0===n?void 0:n.postMessage(`navigate:${e},${t}`,"null"===window.origin?"*":window.origin)});var s;t.addEventListener("load",(()=>{r(q).classList.add("active"),n(e.slide(),e.fragmentIndex),e.on("fragment",(({index:e,fragmentIndex:t})=>n(e,t)))}));const a=document.querySelectorAll(".bespoke-marp-note");a.forEach((e=>{e.addEventListener("keydown",(e=>e.stopPropagation())),r(C).appendChild(e)})),e.on("activate",(()=>a.forEach((t=>t.classList.toggle("active",t.dataset.index==e.slide()))))),e.on("activate",(({index:t})=>{r(K).textContent=`${t+1} / ${e.slides.length}`}));const i=r(j),o=r(R);i.addEventListener("click",(t=>{i.blur(),e.prev({fragment:!t.shiftKey})})),o.addEventListener("click",(t=>{o.blur(),e.next({fragment:!t.shiftKey})})),e.on("fragment",(({index:t,fragments:n,fragmentIndex:r})=>{i.disabled=0===t&&0===r,o.disabled=t===e.slides.length-1&&r===n.length-1}));const l=()=>r(U).textContent=(new Date).toLocaleTimeString();l(),setInterval(l,250)})(e)}function X(e){const t=g();return t===p.Next&&e.appendChild(document.createElement("span")),e=>{t===p.Normal&&function(e){if(!(e=>e.syncKey&&"string"==typeof e.syncKey)(e))throw new Error("The current instance of Bespoke.js is invalid for Marp bespoke presenter plugin.");Object.defineProperties(e,{openPresenterView:{enumerable:!0,value:x},presenterUrl:{enumerable:!0,get:k}}),w.available&&document.addEventListener("keydown",(t=>{80!==t.which||t.altKey||t.ctrlKey||t.metaKey||(t.preventDefault(),e.openPresenterView())}))}(e),t===p.Presenter&&V(e),t===p.Next&&function(e){const t=t=>{if(t.origin!==window.origin)return;const[n,r]=t.data.split(":");if("navigate"===n){const[t,n]=r.split(",");let s=Number.parseInt(t,10),a=Number.parseInt(n,10)+1;a>=e.fragments[s].length&&(s+=1,a=0),e.slide(s,{fragment:a})}};window.addEventListener("message",t),e.on("destroy",(()=>window.removeEventListener("message",t)))}(e)}}function Y(e){e.on("activate",(t=>{document.querySelectorAll(".bespoke-progress-parent > .bespoke-progress-bar").forEach((n=>{n.style.flexBasis=100*t.index/(e.slides.length-1)+"%"}))}))}const B=e=>{const t=Number.parseInt(e,10);return Number.isNaN(t)?null:t};function z(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}},s=(t={fragment:!0})=>{((t,n)=>{const{fragments:r,slides:s}=e,a=Math.max(0,Math.min(t,s.length-1)),i=Math.max(0,Math.min(n||0,r[a].length-1));a===e.slide()&&i===e.fragmentIndex||e.slide(a,{fragment:i})})((B(location.hash.slice(1))||1)-1,t.fragment?B(v("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((()=>{s(),window.addEventListener("hashchange",(()=>r((()=>{s({fragment:!1}),b({f:void 0})})))),window.addEventListener("popstate",(()=>{n||r((()=>s()))})),n=!1}),0)}}let H;function W(e={}){const t=e.key||((e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e));for(;e--;){let r=63&n[e];t+=r<36?r.toString(36):r<62?(r-26).toString(36).toUpperCase():r<63?"_":"-"}return t})(),n=`bespoke-marp-sync-${t}`,r=()=>{const e=w.get(n);return e?JSON.parse(e):Object.create(null)},s=e=>{const t=r(),s=Object.assign(Object.assign({},t),e(t));return w.set(n,JSON.stringify(s)),s};return s((e=>({reference:(e.reference||0)+1}))),e=>{Object.defineProperty(e,"syncKey",{value:t,enumerable:!0});let a=!0;setTimeout((()=>{e.on("fragment",(e=>{a&&s((()=>({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{a=!1,e.slide(r.index,{fragment:r.fragmentIndex})}finally{a=!0}}})),e.on("destroy",(()=>{const{reference:e}=r();void 0===e||e<=1?w.remove(n):s((()=>({reference:e-1})))}))}}function J({slope:e=Math.tan(-35*Math.PI/180),swipeThreshold:t=30}={}){return n=>{let r;const s=n.parent,a=e=>{const t=s.getBoundingClientRect();return{x:e.pageX-(t.left+t.right)/2,y:e.pageY-(t.top+t.bottom)/2}};s.addEventListener("touchstart",(e=>{r=1===e.touches.length?a(e.touches[0]):void 0}),{passive:!0}),s.addEventListener("touchmove",(e=>{if(r)if(1===e.touches.length){e.preventDefault();const t=a(e.touches[0]),n=t.x-r.x,s=t.y-r.y;r.delta=Math.sqrt(Math.pow(Math.abs(n),2)+Math.pow(Math.abs(s),2)),r.radian=Math.atan2(n,s)}else r=void 0})),s.addEventListener("touchend",(s=>{if(r){if(r.delta&&r.delta>=t&&r.radian){let t=r.radian-e;t=(t+Math.PI)%(2*Math.PI)-Math.PI,n[t<0?"next":"prev"](),s.stopPropagation()}r=void 0}}),{passive:!0})}} /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */function _(e,t,n,r){return new(n||(n=Promise))((function(s,a){function i(e){try{l(r.next(e))}catch(e){a(e)}}function o(e){try{l(r.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,o)}l((r=r.apply(e,t||[])).next())}))}const G=()=>(void 0===H&&(H="wakeLock"in navigator&&navigator.wakeLock),H),Q=()=>_(void 0,void 0,void 0,(function*(){const e=G();if(e)try{const t=yield e.request("screen");return t.addEventListener("release",(()=>{console.debug("[Marp CLI] Wake Lock was released")})),console.debug("[Marp CLI] Wake Lock is active"),t}catch(e){console.warn(e)}return null}));function Z(){return _(this,void 0,void 0,(function*(){if(!G())return;let e;const t=()=>{e&&"visible"===document.visibilityState&&Q()};return document.addEventListener("visibilitychange",t),document.addEventListener("fullscreenchange",t),e=yield Q(),e}))}const ee=[p.Normal,p.Presenter,p.Next];!function(r=document.getElementById("p")){document.body.setAttribute(m,(()=>{switch(v("view")){case"next":return p.Next;case"presenter":return p.Presenter;default:return p.Normal}})());const s=(e=>{const t=v(e);return b({[e]:void 0}),t})("sync")||void 0,o=!1,d=!0,f=e(r,((...e)=>{const t=ee.findIndex((e=>g()===e));if(t<0)throw new Error("Invalid view");return e.map((([e,n])=>e[t]&&n)).filter((e=>e))})([[d,d,o],W({key:s})],[[d,d,d],X(r)],[[d,d,o],l],[[d,d,d],t],[[d,o,o],i()],[[d,d,d],c],[[d,d,d],z({history:!1})],[[d,d,o],u()],[[d,d,o],a],[[d,o,o],Y],[[d,d,o],J()],[[d,o,o],y()],[[d,d,d],n],[[d,d,o],Z]));window.addEventListener("beforeunload",(()=>b({sync:f.syncKey}))),window.addEventListener("unload",(()=>f.destroy()))}()}();</script></body></html>