view slide/index.html @ 130:22fc8ae31b50

...
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 08 Feb 2021 00:07:56 +0900
parents 84d494497c92
children 988b3024d685
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="53" 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="53" 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="53" 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="53" 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="53" style="--paginate:true;">
<h1>ノーマル、メタレベルの計算とGearsOS</h1>
<ul>
<li>ノーマルレベル、メタレベルを一貫して記述できる言語CbCを用いてGearsOSを開発している</li>
<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="6" data-paginate="true" data-marpit-pagination="6" data-marpit-pagination-total="53" 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>-&gt;top) {
        data = <span class="hljs-built_in">stack</span>-&gt;top-&gt;data;
        <span class="hljs-built_in">stack</span>-&gt;top = <span class="hljs-built_in">stack</span>-&gt;top-&gt;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="7" data-paginate="true" data-marpit-pagination="7" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>ノーマルレベルでのGearsOSの実装</h1>
<ul>
<li>通常のプログラミング言語のように引数を受け取れる</li>
<li>引数を受け取り、次のCodeGearに継続する
<ul>
<li><code>right_fork-&gt;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-&gt;Rightfork;
    <span class="hljs-keyword">goto</span> right_fork-&gt;checkAndSet(<span class="hljs-number">-1</span>, phils-&gt;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="8" data-paginate="true" data-marpit-pagination="8" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>DataGear</h1>
<ul>
<li>GearsOSで扱うデータの単位</li>
<li>Cの構造体の形でメタレベルでは表現される</li>
<li>InterfaceもDataGearで表現される</li>
<li>GearsOS自体の処理にかかわるMetaDataGearが存在する
<ul>
<li>Context(プロセス)</li>
<li>TaskManager</li>
<li>Worker</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="9" data-paginate="true" data-marpit-pagination="9" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>CodeGear、DataGearの番号</h1>
<ul>
<li>Perlで変換すると番号の形に抽象化される
<ul>
<li>番号から具体的なCodeGear/DataGearを取り出すのはメタレベル</li>
</ul>
</li>
</ul>
</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="53" 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="11" data-paginate="true" data-marpit-pagination="11" data-marpit-pagination-total="53" 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>-&gt;top) {
        data = <span class="hljs-built_in">stack</span>-&gt;top-&gt;data;
        <span class="hljs-built_in">stack</span>-&gt;top = <span class="hljs-built_in">stack</span>-&gt;top-&gt;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="12" data-paginate="true" data-marpit-pagination="12" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>メタに変換されたGearsOSの実装</h1>
<ul>
<li>直接checkAndSetに行かずにmetaに飛ぶ</li>
<li>もとのコードは<code>goto right_fork-&gt;checkAndSet()</code>なので、Interfaceを使った継続
<ul>
<li>context内の継続先のInterfaceの引数格納用の配列に書き込まれる</li>
<li><code>right_fork-&gt;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-&gt;Rightfork;
    Gearef(context, AtomicT_int)-&gt;atomicT_int = (<span class="hljs-keyword">union</span> Data*) right_fork;
    Gearef(context, AtomicT_int)-&gt;oldData = <span class="hljs-number">-1</span>;
    Gearef(context, AtomicT_int)-&gt;newData = phils-&gt;self;
    Gearef(context, AtomicT_int)-&gt;next = C_pickup_lforkPhilsImpl;
    (cGearefontext, AtomicT_int)-&gt;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-&gt;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="13" data-paginate="true" data-marpit-pagination="13" data-marpit-pagination-total="53" 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-&gt;Rightfork;
    <span class="hljs-keyword">goto</span> right_fork-&gt;checkAndSet(<span class="hljs-number">-1</span>, phils-&gt;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-&gt;Rightfork;
    Gearef(context, AtomicT_int)-&gt;atomicT_int = (<span class="hljs-keyword">union</span> Data*) right_fork;
    Gearef(context, AtomicT_int)-&gt;oldData = <span class="hljs-number">-1</span>;
    Gearef(context, AtomicT_int)-&gt;newData = phils-&gt;self;
    Gearef(context, AtomicT_int)-&gt;next = C_pickup_lforkPhilsImpl;
    (cGearefontext, AtomicT_int)-&gt;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-&gt;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="14" data-paginate="true" data-marpit-pagination="14" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>ノーマルレベルでのInterface</h1>
<ul>
<li>GearsOSのモジュール化の仕組みにInterfaceがある</li>
<li>JavaのIntefaceに相当する機能</li>
<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>&lt;</span>&gt;{
        <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="15" data-paginate="true" data-marpit-pagination="15" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>ノーマルレベルのInterfaceの呼び出し</h1>
<ul>
<li><code>goto interface-&gt;method</code>で呼び出せる</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="53" 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)-&gt;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="17" data-paginate="true" data-marpit-pagination="17" data-marpit-pagination-total="53" style="--paginate:true;">
<ul>
<li>メタレベルの処理を全部手で書くのは面倒
<ul>
<li>メタレベルの処理を自動生成してくれるフレームワークを導入したい</li>
</ul>
</li>
<li>フレームワークに乗って実装すると等価なCbCに変換される
<ul>
<li>CbCレベルではメタレベルの処理とノーマルレベルの処理が見れる</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="18" data-paginate="true" data-marpit-pagination="18" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>GearsOSのメタ計算フレームワーク</h1>
<ul>
<li>GearsOSはPerlを中心としたメタコード生成のフレームワークが構築されている
<ul>
<li>計算に必要なデータの入出力のメタ計算を主に生成していた</li>
</ul>
</li>
<li>メタレベルの処理は従来のものは手動で作る方が多かった
<ul>
<li>計算で使うすべてのデータ構造の管理</li>
<li>別のInterfaceの出力を受けるメタレベルのデータ管理など</li>
</ul>
</li>
<li>Perlでメタレベルに変換された後で気づくエラーも多い
<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="19" data-paginate="true" data-marpit-pagination="19" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>GearsOSのメタ計算フレームワークとInterface</h1>
<ul>
<li>CbCには無いモジュール化の仕組みとしてInterfaceがある
<ul>
<li>Perlフレームワーク上に構築</li>
<li>コンパイル時に等価な純粋なCbCに変換する</li>
</ul>
</li>
<li>Interfaceの機能が他の言語のInterfaceの機能とギャップがあった
<ul>
<li>実装していないAPIがあっても、変換前の時点でエラーが出ないなど</li>
</ul>
</li>
<li>Interfaceの定義ファイルもあるものと無いものがあった
<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="20" data-paginate="true" data-marpit-pagination="20" data-marpit-pagination-total="53" 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">&quot;../../../context.h&quot;</span></span>
<span class="hljs-meta">#interface <span class="hljs-meta-string">&quot;Stack.h&quot;</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-&gt;next = <span class="hljs-built_in">stack</span>-&gt;top;
    element-&gt;data = data;
    <span class="hljs-built_in">stack</span>-&gt;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="21" data-paginate="true" data-marpit-pagination="21" data-marpit-pagination-total="53" 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="22" data-paginate="true" data-marpit-pagination="22" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>GearsOSの基礎概念</h1>
<ul>
<li>CodeGear、DataGear</li>
<li>Interface</li>
<li>GearsOSのビルドシステム
<ul>
<li>cmake</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="23" data-paginate="true" data-marpit-pagination="23" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Context(1)</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="24" data-paginate="true" data-marpit-pagination="24" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Context(2)</h1>
<ul>
<li>GearsOSでcontextを触るのはメタ計算部分だけ
<ul>
<li>ノーマルレベルではcontextに触れない</li>
</ul>
</li>
<li>従来は手書きでcontext.hの中で定義</li>
<li>Context自体は構造体で定義されている
<ul>
<li>Contextの要素にDataGearの型がすべて揃った共用体がある<br />
<img src="./context.svg" alt="w:532 h:10cm" style="width:532px;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="25" data-paginate="true" data-marpit-pagination="25" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Interface</h1>
<ul>
<li>GearsOSのモジュール化の仕組み</li>
<li>Interface はある Data Gear と、それに対する操作(API)を行う Code Gear とその操作に用いる Data Gear の集合を表現する。</li>
<li>JavaのInteface、Haskellの型クラスに相当する</li>
<li>ContextにInterfaceの引数の保存場所がある
<ul>
<li>goto時にStubCodeGearでデータをとってくる</li>
</ul>
</li>
<li><code>goto interfaceName-&gt;method()</code>のようにAPIを呼び出す
<ul>
<li>Perlトランスパイラが<code>goto meta()</code>に書き直す</li>
<li><code>goto meta</code>はcontextから引数を取り出すMetaCodeGearに継続させるもの</li>
</ul>
</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="53" 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でエラーを出すとCMakeがビルドを止める
<ul>
<li>従来はエラーを出していなかったので怪しいコードを生成しても止まらない<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="27" data-paginate="true" data-marpit-pagination="27" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>GearsOSのビルドシステム</h1>
<ul>
<li>generate_stub.pl
<ul>
<li>GearsOSで拡張したCbCを1行ずつ読む</li>
<li>純粋なCbCに変形したものを生成する</li>
<li>CbCコンパイラがコンパイルする前にコードを変換する
<ul>
<li>ユーザーが書いたGearsOSのソースコードにメタ情報をつける</li>
<li>コードからコードを生成する、トランスパイラ</li>
</ul>
</li>
</ul>
</li>
<li>generate_context.pl
<ul>
<li>Contextに関係するファイルを生成する
<ul>
<li>Contextの初期化ルーチン</li>
<li>CodeGear/DataGearの番号(enum)</li>
</ul>
</li>
<li>変換したプロジェクトで使うすべてのCbCファイルを入力で受け取る</li>
<li>すべてのCbCファイルを読み込み、使用しているCodeGearなどの情報を取得</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="53" 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="29" data-paginate="true" data-marpit-pagination="29" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Interfaceシステムの強化</h1>
<ul>
<li>Interface構文の簡素化
<ul>
<li>より簡潔に明確に記述できるように定義した。</li>
</ul>
</li>
<li>Interfaceの実装の型の導入
<ul>
<li>GearsOSでの型定義の方法に一貫性が生まれた</li>
</ul>
</li>
<li>Interfaceの引数の確認</li>
<li>Interfaceで未定義のAPIの検知</li>
<li>InterfaceにないAPIの呼び出しの検知
<ul>
<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="30" data-paginate="true" data-marpit-pagination="30" data-marpit-pagination-total="53" 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="31" data-paginate="true" data-marpit-pagination="31" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>GearsOSの新機能</h1>
<ul>
<li><strong>自由なMetaCodeGearの作製、継続の入れ替え機能</strong></li>
<li>Perlトランスパイラの変換ルーチンのデバッグ機能の追加</li>
<li>ジェネリクスのサポート</li>
</ul>
</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="53" 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="33" data-paginate="true" data-marpit-pagination="33" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Interfaceの定義構文の改良</h1>
<ul>
<li>従来は引数とCodeGearの定義を別けて記述していた
<ul>
<li>Interfaceの宣言なので、書ける変数は引数/出力のもののみ</li>
</ul>
</li>
<li>Javaのクラス変数やインスタンス変数のようなものだと思われてしまった
<ul>
<li>GearsOSに慣れてない</li>
<li>シンタックスが問題</li>
</ul>
</li>
<li>シンタックスをgolangやJavaのInterfaceを参考に簡潔なものにした</li>
</ul>
</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="53" style="--paginate:true;">
<h1>従来のInterface</h1>
<ul>
<li>引数の組とAPI(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>&lt;</span>Type, Impl&gt;{
        <span class="hljs-class"><span class="hljs-keyword">union</span> <span class="hljs-title">Data</span>* <span class="hljs-title">stack</span>;</span>
        <span class="hljs-class"><span class="hljs-keyword">union</span> <span class="hljs-title">Data</span>* <span class="hljs-title">data</span>;</span>
        <span class="hljs-class"><span class="hljs-keyword">union</span> <span class="hljs-title">Data</span>* <span class="hljs-title">data1</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="35" data-paginate="true" data-marpit-pagination="35" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>定義し直したInterface構文</h1>
<ul>
<li>APIのみを記述すれば良くなった</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></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="53" style="--paginate:true;">
<h1>Implementの型定義ファイルの導入</h1>
<ul>
<li>Interfaceは型定義ファイルがあったが、実装側はなかった</li>
<li>context.h上にメタな構造体に直した実装の型を手で書いていた
<ul>
<li>これはメタ情報なので手で書きたくない</li>
<li>型定義の一貫性がない</li>
</ul>
</li>
<li>実装側にも型定義ファイルを導入して一貫性を持たせたい
<ul>
<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="37" data-paginate="true" data-marpit-pagination="37" data-marpit-pagination-total="53" 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> &lt;</span>&gt; 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="38" data-paginate="true" data-marpit-pagination="38" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Interfaceの実装時の型名の省略</h1>
<ul>
<li>従来は型名を必ず書かなければならなかった
<ul>
<li>これはメタ情報なので変換時に書き換える</li>
</ul>
</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_lforkPhilsImpl</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-&gt;Leftfork;
    <span class="hljs-keyword">goto</span> left_fork-&gt;checkAndSet(<span class="hljs-number">-1</span>, phils-&gt;self, pickup_rforkPhilsImpl, eatingPhilsImpl);

}
</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_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-&gt;Leftfork;
    <span class="hljs-keyword">goto</span> left_fork-&gt;checkAndSet(<span class="hljs-number">-1</span>, phils-&gt;self, pickup_rfork, eating);

}
</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="53" style="--paginate:true;">
<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-&gt;Leftfork;
    <span class="hljs-keyword">goto</span> left_fork-&gt;checkAndSet(<span class="hljs-number">-1</span>, phils-&gt;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-&gt;Leftfork;
    Gearef(context, AtomicT_int)-&gt;atomicT_int = (<span class="hljs-keyword">union</span> Data*) left_fork;
    Gearef(context, AtomicT_int)-&gt;oldData = <span class="hljs-number">-1</span>;
    Gearef(context, AtomicT_int)-&gt;newData = phils-&gt;self;
    Gearef(context, AtomicT_int)-&gt;next = C_pickup_rforkPhilsImpl;
    Gearef(context, AtomicT_int)-&gt;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-&gt;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="40" data-paginate="true" data-marpit-pagination="40" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>Interfaceのパーサーの導入</h1>
<ul>
<li>PerlでのInterfaceの情報の取得は、CbC自体のファイルの解析処理と共通だった
<ul>
<li>Interfaceならではの情報が取れない</li>
<li>スクリプトに直接書かれているので他のツールが使えない</li>
</ul>
</li>
<li>モジュール化したInterfaceのパーサーを導入した
<ul>
<li>Perlフレームワークを使う一連のツールの作製が可能になった
<ul>
<li>InterfaceとImplを見た実装の雛形ファイルの作製ツール</li>
<li>コード変換時にInterfaceのAPIに関連するチェック機能</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="41" data-paginate="true" data-marpit-pagination="41" data-marpit-pagination-total="53" 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>
</tbody>
</table>
</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="53" style="--paginate:true;">
<h1>Interfaceの実装の雛形生成コマンドの実装</h1>
<ul>
<li>Interfaceと実装する型が決まると、最低限書かないといけないCodeGearが決まる</li>
<li>従来は手作業でCbCファイルにCodeGearの定義を書いて実装していた
<ul>
<li>コンストラクタも手書き</li>
</ul>
</li>
<li>JavaはIDEで、golangはコマンドとして雛形を生成するものを用意している
<ul>
<li>GearsOSでも導入した</li>
</ul>
</li>
<li>実装の型ファイルを引数で渡すと雛形を生成する</li>
</ul>
<pre><code class="language-shell"><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><span class="bash">perl too/impl2cbc.pl SingleLinkedStack.h</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="43" data-paginate="true" data-marpit-pagination="43" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>PerlトランスパイラでのInterfaceのエラー生成</h1>
<ul>
<li>Interfaceの実装時に様々なミスをする可能性がある
<ul>
<li>APIを完全に実装していない</li>
<li>呼び出しの引数を間違えている</li>
<li>無いAPIを呼び出している</li>
</ul>
</li>
<li>従来は変換した後CbCコンパイラがコンパイルする際や、実行時にしかエラーが出なかった
<ul>
<li>どの記述でエラーが出たのかの特定が困難</li>
<li>CbCコンパイラがコンパイルする前にトランスパイラで検知したい</li>
</ul>
</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="53" style="--paginate:true;">
<h1>実装をし忘れているAPIがあった場合のエラー終了</h1>
<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="45" data-paginate="true" data-marpit-pagination="45" data-marpit-pagination-total="53" 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>
<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></span></foreignObject></svg></code></pre>
</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="53" style="--paginate:true;">
<h1>StubCodeGear</h1>
<ul>
<li>実行したいCodeGearの直前に実行されるMetaCodeGear</li>
<li>contextからDataGearを取り出す操作をする</li>
<li>すべてのノーマルレベルのCodeGearに付随する
<ul>
<li>Perlトランスパイラでビルド時に自動生成<br />
<img src="./stubCodeGear.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="47" data-paginate="true" data-marpit-pagination="47" data-marpit-pagination-total="53" style="--paginate:true;">
<h2>別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成</h2>
<ul>
<li>Stackから<code>data</code>と<code>data1</code>を受け取ろうとする例
<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-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>-&gt;pop2(pop2Test1);
}


<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">&quot;%d\n&quot;</span>, str-&gt;size);
    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d\n&quot;</span>, str2-&gt;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="48" data-paginate="true" data-marpit-pagination="48" data-marpit-pagination-total="53" style="--paginate:true;">
<h2>別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成</h2>
<ul>
<li>Interfaceの継続に別のInterfaceを渡すと値の受け渡しが上手くいかない
<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">pop2Test1StackTestImpl3_stub</span><span class="hljs-params">(struct Context* context)</span> </span>{
  StackTestImpl3* stackTest = (StackTestImpl3*)GearImpl(context, StackTest, stackTest);
  Data* data = Gearef(context, StackTest)-&gt;data;
  Data* data1 = Gearef(context, StackTest)-&gt;data1;
  Stack* <span class="hljs-built_in">stack</span> = Gearef(context, StackTest)-&gt;<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)-&gt;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="49" data-paginate="true" data-marpit-pagination="49" data-marpit-pagination-total="53" style="--paginate:true;">
<ul>
<li>メタ計算部分で取得するcontextの場所が異なっているのが問題
<ul>
<li>取得する場所を手書きする必要があった</li>
</ul>
</li>
</ul>
<p><img src="./stackTest1.svg" alt="w:732 h:13cm" style="width:732px;height:13cm;" /></p>
</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="53" style="--paginate:true;">
<h2>別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成</h2>
<ul>
<li><code>goto interface-&gt;method()</code>している箇所を読み取る
<ul>
<li><code>interface</code>がどのInterfaceなのかをPerlトランスパイラで特定させた</li>
<li>特定したInterfaceをパーサーを呼び出して情報を取得</li>
<li>APIごとに出力があるかを調査</li>
</ul>
</li>
<li>出力があったら、継続で渡しているCodeGearの入力を、呼び出しているInterfaceからとるように修正
<ul>
<li>データの取り出しはStubでしているので、新たなStubを作製した</li>
</ul>
</li>
</ul>
</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="53" 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)-&gt;data;
  Data* data1 = Gearef(context, StackTest)-&gt;data1;
  Stack* <span class="hljs-built_in">stack</span> = Gearef(context, StackTest)-&gt;<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)-&gt;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)-&gt;data;
  Data* data1 = Gearef(context, Stack)-&gt;data1;
  Stack* <span class="hljs-built_in">stack</span> = Gearef(context, StackTest)-&gt;<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)-&gt;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="52" data-paginate="true" data-marpit-pagination="52" data-marpit-pagination-total="53" style="--paginate:true;">
<h1>メタ計算の切り替えAPI</h1>
<ul>
<li>CodeGearが継続するMetaCodeGearを自由に選択できるPerlモジュールを導入した
<ul>
<li>従来はデフォルトで設定されるMetaCodeGearにしか継続しなかった</li>
<li>Perlモジュールを書くことで特定のCodeGearの継続先を変更可能にした</li>
</ul>
</li>
<li>様々な処理をMetaCodeGearですることが可能になった
<ul>
<li>すでにモデル検査用のメタ計算を入れることが出来た</li>
</ul>
</li>
</ul>
<p><img src="./metapm.svg" alt="w:932 h:10cm" style="width:932px;height:10cm;" /></p>
</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="53" 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>
<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>