diff --git a/stack--current/0-meta/typescript-custom-typings/experimental.d.ts b/stack--current/0-meta/typescript-custom-typings/experimental.d.ts new file mode 100644 index 00000000..5cbb7576 --- /dev/null +++ b/stack--current/0-meta/typescript-custom-typings/experimental.d.ts @@ -0,0 +1,9 @@ + +// https://mariusschulz.com/blog/declaring-global-variables-in-typescript + +declare var ai: { + assistant?: any + summarizer?: any + writer?: any + rewriter?: any +} diff --git a/stack--current/3-advanced--browser/css--foundation/public/index.css b/stack--current/3-advanced--browser/css--foundation/public/index.css index 4a06eebf..9c004b53 100644 --- a/stack--current/3-advanced--browser/css--foundation/public/index.css +++ b/stack--current/3-advanced--browser/css--foundation/public/index.css @@ -1 +1 @@ -@layer offirmo--foundation{:root{--o⋄color⁚fg--link--default:#00f;--o⋄color⁚fg--link--visited--default:#531a89;--o⋄color⁚fg--activity-outline--default:#4d91fe;--o⋄color⁚fg--accent--default:#07f;--o⋄font-family--system--sans:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Segoe UI","Helvetica Neue",Helvetica,Cantarell,Ubuntu,Roboto,Noto,Arial,sans-serif;--o⋄font-family--system--mono:ui-monospace,Menlo,Consolas,Monaco,"Liberation Mono","Lucida Console",monospace,monospace;--o⋄font-family--system--serif:ui-serif,"Iowan Old Style","Apple Garamond",Baskerville,"Times New Roman","Droid Serif",Times,"Source Serif Pro",serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}a{color:var(--o⋄color⁚fg--link);touch-action:manipulation;&:visited{color:var(--o⋄color⁚fg--link--visited)}&:hover,&:active{color:var(--o⋄color⁚fg--activity-outline)}}blockquote>p:first-of-type:before{content:open-quote}blockquote>p:last-of-type:after{content:close-quote}blockquote>p{display:inline-block}body{max-width:var(--o⋄content-recommended-width);margin:0 max(1ch,(100vw - var(--o⋄content-recommended-width))/2);padding:0}dl{grid-template-columns:max-content 1fr;display:grid}figure{text-align:center;& img{margin:auto}}hr{border:none;border-top:var(--o⋄border--thickness)solid;background-color:var(--o⋄color⁚fg--ancillary);width:100%}iframe{border:0}img{image-orientation:from-image;object-fit:cover;background-color:var(--o⋄color⁚bg--highlight--1);image-rendering:-webkit-optimize-contrast;max-width:100%}nav{& :is(ol,ul){flex-direction:row;gap:2em;padding-inline-start:0;list-style-type:none;display:flex}}p{text-wrap:pretty}strong{color:var(--o⋄color⁚fg--strong)}svg|a{color:var(--o⋄color⁚fg--link);touch-action:manipulation;&:visited{color:var(--o⋄color⁚fg--link--visited)}&:hover,&:active{color:var(--o⋄color⁚fg--activity-outline)}&:link,&:visited{cursor:pointer}&,& text{fill:var(--o⋄color⁚fg--link);text-decoration:underline}&:hover,&:active{outline:dotted var(--o⋄border--thickness)var(--o⋄color⁚fg--activity-outline)}}textarea{form-sizing:normal}details{border:dashed var(--o⋄border--thickness);padding-inline-start:1.4rem}details summary{cursor:pointer;margin-inline-start:-1rem}details summary>*{display:inline}details[open]{border-color:var(--o⋄color⁚fg--main)}:is(h1,h2,h3,h4,h5,h6){color:var(--o⋄color⁚fg--strong);text-wrap:balance;margin-block:.5em}[id]:is(h1,h2,h3,h4,h5,h6){scroll-margin-top:2ex}:root{accent-color:var(--o⋄color⁚fg--accent)}ul,ol{padding-inline-start:1.5em}code,kbd,pre,samp{font-family:var(--o⋄font-family--code);background:var(--o⋄color⁚bg--code);border-radius:.2em;padding-inline:.5ch;font-size:.9em}img,video{max-width:100%;display:block}table{table-layout:fixed;border-collapse:collapse}td{font-variant-numeric:tabular-nums}tbody tr:nth-child(odd){background-color:var(--o⋄color⁚bg--highlight--1)}thead{position:sticky;top:0}:root{scrollbar-color:var(--o⋄color⁚bg--highlight--1)var(--o⋄color⁚bg--main);scrollbar-width:thin}*,:before,:after{scrollbar-color:inherit;scrollbar-width:inherit}::-webkit-scrollbar{xxwidth:.5rem}::-webkit-scrollbar-thumb{background-color:var(--o⋄color⁚bg--highlight--2)}:root{box-sizing:border-box}*,:before,:after{box-sizing:inherit}.box-sizing-reset{box-sizing:initial}:root{color:var(--o⋄color⁚fg--main);background-color:var(--o⋄color⁚bg--main);scroll-behavior:smooth}*{touch-action:manipulation}:root{--o⋄header__scale-ratio:2;font-size:100%}:is(h1,h2,h3,h4){font-size:calc(1rem*(1 + ((var(--o⋄header__scale-ratio) - 1)*var(--o⋄header__scale-ratio__modifier))))}h1{--o⋄header__scale-ratio__modifier:calc(3/3)}h2{--o⋄header__scale-ratio__modifier:calc(2/3)}h3{--o⋄header__scale-ratio__modifier:calc(1/3)}h4{--o⋄header__scale-ratio__modifier:calc(0/3)}small{font-size:.8rem}:root{font-family:var(--o⋄font-family--main);font-variant-numeric:slashed-zero;text-decoration-thickness:var(--o⋄border--thickness);-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;text-rendering:geometricprecision;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.5}.offirmo--layer--debug{color:#00f}}@layer offirmo--foundation.offirmo--foundation{:root{--o⋄color⁚fg--main:#000;--o⋄color⁚bg--main:#fff;--o⋄color⁚fg--strong:var(--o⋄color⁚fg--main);--o⋄color⁚fg--accent:var(--o⋄color⁚fg--accent--default);--o⋄color⁚fg--link:var(--o⋄color⁚fg--link--default);--o⋄color⁚fg--link--visited:var(--o⋄color⁚fg--link--visited--default);--o⋄color⁚fg--activity-outline:var(--o⋄color⁚fg--activity-outline--default);--o⋄color⁚bg--code:#ededed;--o⋄color⁚bg--highlight--1:#0000001a;--o⋄color⁚bg--highlight--2:#0000004d;--o⋄font-family--fast_and_good_enough:var(--o⋄font-family--system--sans);--o⋄font-family--main:var(--o⋄font-family--fast_and_good_enough);--o⋄font-family--code:var(--o⋄font-family--system--mono);--o⋄border--thickness:.07rem;--o⋄content-recommended-width:60ch}} \ No newline at end of file +@layer offirmo--foundation{:root{--o⋄color⁚fg--link--default:#00f;--o⋄color⁚fg--link--visited--default:#531a89;--o⋄color⁚activity-outline--default:#4d91fe;--o⋄color⁚accent--default:#07f;--o⋄font-family--system--sans:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Segoe UI","Helvetica Neue",Helvetica,Cantarell,Ubuntu,Roboto,Noto,Arial,sans-serif;--o⋄font-family--system--mono:ui-monospace,Menlo,Consolas,Monaco,"Liberation Mono","Lucida Console",monospace,monospace;--o⋄font-family--system--serif:ui-serif,"Iowan Old Style","Apple Garamond",Baskerville,"Times New Roman","Droid Serif",Times,"Source Serif Pro",serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}a,svg|a{color:var(--o⋄color⁚fg--link);text-decoration-thickness:var(--o⋄border--thickness);touch-action:manipulation;&:visited{color:var(--o⋄color⁚fg--link--visited)}&:hover{background-color:var(--o⋄color⁚bg--highlight--1)}&:active{color:var(--o⋄color⁚activity-outline)}}blockquote>p:first-of-type:before{content:open-quote}blockquote>p:last-of-type:after{content:close-quote}blockquote>p{display:inline-block}body{max-width:var(--o⋄content-recommended-width);margin:0 max(1ch,(100vw - var(--o⋄content-recommended-width))/2);padding:0}dl{grid-template-columns:max-content 1fr;display:grid}figure{text-align:center;& img{margin:auto}}hr{border:none;border-top:var(--o⋄border--thickness)solid;background-color:var(--o⋄color⁚fg--ancillary);width:100%}iframe{border:0}img{image-orientation:from-image;object-fit:cover;background-color:var(--o⋄color⁚bg--highlight--1);image-rendering:-webkit-optimize-contrast;max-width:100%}nav{& :is(ol,ul){flex-direction:row;gap:2em;padding-inline-start:0;list-style-type:none;display:flex}}p{text-wrap:pretty}strong{color:var(--o⋄color⁚fg--strong)}svg|a{&:link,&:visited{cursor:pointer}&,& text{fill:var(--o⋄color⁚fg--link);text-decoration:underline}&:hover,&:active{outline:dotted var(--o⋄border--thickness)var(--o⋄color⁚activity-outline)}}textarea{form-sizing:normal}details{border:dashed var(--o⋄border--thickness);padding-inline-start:1.4rem}details summary{cursor:pointer;margin-inline-start:-1rem}details summary>*{display:inline}details[open]{border-color:var(--o⋄color⁚fg--main)}:is(h1,h2,h3,h4,h5,h6){color:var(--o⋄color⁚fg--strong);text-wrap:balance;margin-block:.5em}[id]:is(h1,h2,h3,h4,h5,h6){scroll-margin-top:2ex}:root{accent-color:var(--o⋄color⁚accent)}ul,ol{padding-inline-start:1.5em}code,kbd,pre,samp{font-family:var(--o⋄font-family--code);background:var(--o⋄color⁚bg--code);border-radius:.2em;padding-inline:.5ch;font-size:.9em}img,video{max-width:100%;display:block}table{table-layout:fixed;border-collapse:collapse}td{font-variant-numeric:tabular-nums}tbody tr:nth-child(odd){background-color:var(--o⋄color⁚bg--highlight--1)}thead{position:sticky;top:0}:root{scrollbar-color:var(--o⋄color⁚bg--highlight--1)var(--o⋄color⁚bg--main);scrollbar-width:thin}*,:before,:after{scrollbar-color:inherit;scrollbar-width:inherit}::-webkit-scrollbar{xxwidth:.5rem}::-webkit-scrollbar-thumb{background-color:var(--o⋄color⁚bg--highlight--2)}:root{box-sizing:border-box}*,:before,:after{box-sizing:inherit}.box-sizing-reset{box-sizing:initial}:root{color:var(--o⋄color⁚fg--main);background-color:var(--o⋄color⁚bg--main);scroll-behavior:smooth}*{touch-action:manipulation}:root{--o⋄header__scale-ratio:2;font-size:100%}:is(h1,h2,h3,h4){font-size:calc(1rem*(1 + ((var(--o⋄header__scale-ratio) - 1)*var(--o⋄header__scale-ratio__modifier))))}h1{--o⋄header__scale-ratio__modifier:calc(3/3)}h2{--o⋄header__scale-ratio__modifier:calc(2/3)}h3{--o⋄header__scale-ratio__modifier:calc(1/3)}h4{--o⋄header__scale-ratio__modifier:calc(0/3)}small{font-size:.8rem}:root{font-family:var(--o⋄font-family--main);font-variant-numeric:slashed-zero;text-decoration-thickness:var(--o⋄border--thickness);-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;text-rendering:geometricPrecision;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.5}.offirmo--layer--debug{color:#00f}}@layer offirmo--foundation.offirmo--foundation{:root{--o⋄color⁚fg--main:#000;--o⋄color⁚bg--main:#fff;--o⋄color⁚fg--strong:var(--o⋄color⁚fg--main);--o⋄color⁚accent:var(--o⋄color⁚accent--default);--o⋄color⁚fg--link:var(--o⋄color⁚fg--link--default);--o⋄color⁚fg--link--visited:var(--o⋄color⁚fg--link--visited--default);--o⋄color⁚activity-outline:var(--o⋄color⁚activity-outline--default);--o⋄color⁚bg--code:#ededed;--o⋄color⁚bg--highlight--1:#0000001a;--o⋄color⁚bg--highlight--2:#0000004d;--o⋄font-family--fast_and_good_enough:var(--o⋄font-family--system--sans);--o⋄font-family--main:var(--o⋄font-family--fast_and_good_enough);--o⋄font-family--code:var(--o⋄font-family--system--mono);--o⋄border--thickness:.07rem;--o⋄content-recommended-width:60ch}} \ No newline at end of file diff --git a/stack--current/3-advanced--browser/css--framework/package.json b/stack--current/3-advanced--browser/css--framework/package.json index 25d178a8..543dd4b9 100644 --- a/stack--current/3-advanced--browser/css--framework/package.json +++ b/stack--current/3-advanced--browser/css--framework/package.json @@ -16,8 +16,8 @@ "scripts": { "clean": "monorepo-script--clean-package …dist …cache", - "_parcel:serve": "parcel serve --log-level verbose 'doc/demo/*.html' --port 3030 --no-autoinstall", - "dev": "npm-run-all clean --parallel _parcel:serve", + "serve--parcel": "parcel serve --log-level verbose 'doc/demo/*.html' --port 3030 --no-autoinstall", + "dev": "npm-run-all clean --parallel serve--parcel", "build": "node ./src/~~gen/bundle.mjs" }, diff --git a/stack--current/3-advanced--browser/css--framework/public/index.css b/stack--current/3-advanced--browser/css--framework/public/index.css new file mode 100644 index 00000000..ed706c82 --- /dev/null +++ b/stack--current/3-advanced--browser/css--framework/public/index.css @@ -0,0 +1,709 @@ +@layer offirmo--foundation { + :root { + --o⋄color⁚fg--link--default: #00f; + --o⋄color⁚fg--link--visited--default: #531a89; + --o⋄color⁚activity-outline--default: #4d91fe; + --o⋄color⁚accent--default: #07f; + --o⋄font-family--system--sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Avenir Next", Avenir, "Segoe UI", "Helvetica Neue", Helvetica, Cantarell, Ubuntu, Roboto, Noto, Arial, sans-serif; + --o⋄font-family--system--mono: ui-monospace, Menlo, Consolas, Monaco, "Liberation Mono", "Lucida Console", monospace, monospace; + --o⋄font-family--system--serif: ui-serif, "Iowan Old Style", "Apple Garamond", Baskerville, "Times New Roman", "Droid Serif", Times, "Source Serif Pro", serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" + } + + a, svg|a { + color: var(--o⋄color⁚fg--link); + text-decoration-thickness: var(--o⋄border--thickness); + touch-action: manipulation; + + &:visited { + color: var(--o⋄color⁚fg--link--visited) + } + + &:hover { + background-color: var(--o⋄color⁚bg--highlight--1) + } + + &:active { + color: var(--o⋄color⁚activity-outline) + } + } + + blockquote > p:first-of-type:before { + content: open-quote + } + + blockquote > p:last-of-type:after { + content: close-quote + } + + blockquote > p { + display: inline-block + } + + body { + max-width: var(--o⋄content-recommended-width); + margin: 0 max(1ch, (100vw - var(--o⋄content-recommended-width)) / 2); + padding: 0 + } + + dl { + grid-template-columns:max-content 1fr; + display: grid + } + + figure { + text-align: center; + + & img { + margin: auto + } + } + + hr { + border: none; + border-top: var(--o⋄border--thickness) solid; + background-color: var(--o⋄color⁚fg--ancillary); + width: 100% + } + + iframe { + border: 0 + } + + img { + image-orientation: from-image; + object-fit: cover; + background-color: var(--o⋄color⁚bg--highlight--1); + image-rendering: -webkit-optimize-contrast; + max-width: 100% + } + + nav { + & :is(ol,ul) { + flex-direction: row; + gap: 2em; + padding-inline-start: 0; + list-style-type: none; + display: flex + } + } + + p { + text-wrap: pretty + } + + strong { + color: var(--o⋄color⁚fg--strong) + } + + svg|a { + &:link, &:visited { + cursor: pointer + } + + &, & text { + fill: var(--o⋄color⁚fg--link); + text-decoration: underline + } + + &:hover, &:active { + outline: dotted var(--o⋄border--thickness) var(--o⋄color⁚activity-outline) + } + } + + textarea { + form-sizing: normal + } + + details { + border: dashed var(--o⋄border--thickness); + padding-inline-start: 1.4rem + } + + details summary { + cursor: pointer; + margin-inline-start: -1rem + } + + details summary > * { + display: inline + } + + details[open] { + border-color: var(--o⋄color⁚fg--main) + } + + :is(h1,h2,h3,h4,h5,h6) { + color: var(--o⋄color⁚fg--strong); + text-wrap: balance; + margin-block: .5em + } + + [id]:is(h1,h2,h3,h4,h5,h6) { + scroll-margin-top: 2ex + } + + :root { + accent-color: var(--o⋄color⁚accent) + } + + ul, ol { + padding-inline-start: 1.5em + } + + code, kbd, pre, samp { + font-family: var(--o⋄font-family--code); + background: var(--o⋄color⁚bg--code); + border-radius: .2em; + padding-inline: .5ch; + font-size: .9em + } + + img, video { + max-width: 100%; + display: block + } + + table { + table-layout: fixed; + border-collapse: collapse + } + + td { + font-variant-numeric: tabular-nums + } + + tbody tr:nth-child(odd) { + background-color: var(--o⋄color⁚bg--highlight--1) + } + + thead { + position: sticky; + top: 0 + } + + :root { + scrollbar-color: var(--o⋄color⁚bg--highlight--1) var(--o⋄color⁚bg--main); + scrollbar-width: thin + } + + *, :before, :after { + scrollbar-color: inherit; + scrollbar-width: inherit + } + + ::-webkit-scrollbar { + xxwidth: .5rem + } + + ::-webkit-scrollbar-thumb { + background-color: var(--o⋄color⁚bg--highlight--2) + } + + :root { + box-sizing: border-box + } + + *, :before, :after { + box-sizing: inherit + } + + .box-sizing-reset { + box-sizing: initial + } + + :root { + color: var(--o⋄color⁚fg--main); + background-color: var(--o⋄color⁚bg--main); + scroll-behavior: smooth + } + + * { + touch-action: manipulation + } + + :root { + --o⋄header__scale-ratio: 2; + font-size: 100% + } + + :is(h1,h2,h3,h4) { + font-size: calc(1rem * (1 + ((var(--o⋄header__scale-ratio) - 1) * var(--o⋄header__scale-ratio__modifier)))) + } + + h1 { + --o⋄header__scale-ratio__modifier: calc(3 / 3) + } + + h2 { + --o⋄header__scale-ratio__modifier: calc(2 / 3) + } + + h3 { + --o⋄header__scale-ratio__modifier: calc(1 / 3) + } + + h4 { + --o⋄header__scale-ratio__modifier: calc(0 / 3) + } + + small { + font-size: .8rem + } + + :root { + font-family: var(--o⋄font-family--main); + font-variant-numeric: slashed-zero; + text-decoration-thickness: var(--o⋄border--thickness); + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + text-size-adjust: none; + text-rendering: geometricPrecision; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + line-height: 1.5 + } + + .offirmo--layer--debug { + color: #00f + } +} + +@layer offirmo--foundation.offirmo--foundation { + :root { + --o⋄color⁚fg--main: #000; + --o⋄color⁚bg--main: #fff; + --o⋄color⁚fg--strong: var(--o⋄color⁚fg--main); + --o⋄color⁚accent: var(--o⋄color⁚accent--default); + --o⋄color⁚fg--link: var(--o⋄color⁚fg--link--default); + --o⋄color⁚fg--link--visited: var(--o⋄color⁚fg--link--visited--default); + --o⋄color⁚activity-outline: var(--o⋄color⁚activity-outline--default); + --o⋄color⁚bg--code: #ededed; + --o⋄color⁚bg--highlight--1: #0000001a; + --o⋄color⁚bg--highlight--2: #0000004d; + --o⋄font-family--fast_and_good_enough: var(--o⋄font-family--system--sans); + --o⋄font-family--main: var(--o⋄font-family--fast_and_good_enough); + --o⋄font-family--code: var(--o⋄font-family--system--mono); + --o⋄border--thickness: .07rem; + --o⋄content-recommended-width: 60ch + } +} + +@layer offirmo--framework { + :root { + --chromeless-area-inset-top: 0px; + --chromeless-area-inset-right: 0px; + --chromeless-area-inset-bottom: 0px; + --chromeless-area-inset-left: 0px; + --fold-top: env(fold-top, 0px); + --fold-right: env(fold-right, 0px); + --fold-bottom: env(fold-bottom, 0px); + --fold-left: env(fold-left, 0px); + --safe-area-inset-top: env(safe-area-inset-top, 0px); + --safe-area-inset-right: env(safe-area-inset-right, 0px); + --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px); + --safe-area-inset-left: env(safe-area-inset-left, 0px); + --keyboard-inset-top: env(keyboard-inset-top, 0px); + --keyboard-inset-right: env(keyboard-inset-right, 0px); + --keyboard-inset-bottom: env(keyboard-inset-bottom, 0px); + --keyboard-inset-left: env(keyboard-inset-left, 0px); + --keyboard-inset-width: env(keyboard-inset-width, 0px); + --keyboard-inset-height: env(keyboard-inset-height, 0px); + --titlebar-area-x: env(titlebar-area-x, 0px); + --titlebar-area-y: env(titlebar-area-y, 0px); + --titlebar-area-width: env(titlebar-area-width, 0px); + --titlebar-area-height: env(titlebar-area-height, 0px); + --o⋄min-target-size: 36px; + --o⋄icon-size--chrome: 24px; + --o⋄icon-size--tree: 20px; + --o⋄icon-size--functional: 16px; + --o⋄margin-from-screen-border--visual: 4px; + --o⋄margin-from-screen-border--touch: 8px + } + + :root { + --o⋄color⁚boz__gray: #999; + --o⋄color⁚boz__yellow: #f1da32; + --o⋄color⁚boz__pink: #f56bcb; + --o⋄color⁚boz__green: #94e453; + --o⋄color⁚boz__cyan: #1beeee; + --o⋄color⁚boz__blue: #34b0ea; + --o⋄color⁚boz__purple: #c394f5; + --o⋄color⁚darker--10: #0000001a; + --o⋄color⁚darker--20: #0003; + --o⋄color⁚darker--33: #0005; + --o⋄color⁚darker--50: #00000080; + --o⋄color⁚darker--66: #000a; + --o⋄color⁚darker--90: #000000e6; + --o⋄color⁚lighter--10: #ffffff1a; + --o⋄color⁚lighter--20: #fff3; + --o⋄color⁚lighter--33: #fff5; + --o⋄color⁚lighter--66: #fffa; + --o⋄color⁚lighter--90: #ffffffe6 + } + + [data-o-theme], .o⋄error-report { + color: var(--o⋄color⁚fg--main); + background-color: var(--o⋄color⁚bg--main); + accent-color: var(--o⋄color⁚accent); + scrollbar-color: var(--o⋄color⁚bg--highlight--1) var(--o⋄color⁚bg--main) + } + + :root:not([data-o-theme]), [data-o-theme^=light] { + --o⋄color⁚fg--main: black; + --o⋄color⁚fg--secondary: oklch(from var(--o⋄color⁚fg--main) l c h/66%); + --o⋄color⁚fg--ancillary: oklch(from var(--o⋄color⁚fg--main) l c h/33%); + --o⋄color⁚fg--strong: var(--o⋄color⁚fg--main); + --o⋄color⁚bg--main: white; + --o⋄color⁚bg--code: #e6e6e6; + --o⋄color⁚bg--main--backdrop: var(--o⋄color⁚darker--66); + --o⋄color⁚bg--highlight--1: var(--o⋄color⁚darker--10); + --o⋄color⁚bg--highlight--2: var(--o⋄color⁚darker--33); + --o⋄color⁚accent: var(--o⋄color⁚accent--default); + --o⋄color⁚activity-outline: var(--o⋄color⁚activity-outline--default); + --o⋄color⁚fg--link: var(--o⋄color⁚fg--link--default); + --o⋄color⁚fg--link--visited: var(--o⋄color⁚fg--link--visited--default); + --o⋄color⁚fg--error: #e50000; + --o⋄color⁚fg--warning: #990; + --o⋄color⁚fg--info: #00a6b2; + --o⋄color⁚fg--success: #00a600 + } + + [data-o-theme^=dark], .o⋄error-report { + --o⋄color⁚fg--main: white; + --o⋄color⁚fg--secondary: oklch(from var(--o⋄color⁚fg--main) l c h/66%); + --o⋄color⁚fg--ancillary: oklch(from var(--o⋄color⁚fg--main) l c h/33%); + --o⋄color⁚fg--strong: var(--o⋄color⁚fg--main); + --o⋄color⁚bg--main: black; + --o⋄color⁚bg--code: #404040; + --o⋄color⁚bg--main--backdrop: var(--o⋄color⁚darker--66); + --o⋄color⁚bg--highlight--1: var(--o⋄color⁚lighter--20); + --o⋄color⁚bg--highlight--2: var(--o⋄color⁚lighter--33); + --o⋄color⁚accent: var(--o⋄color⁚accent--default); + --o⋄color⁚activity-outline: var(--o⋄color⁚activity-outline--default); + --o⋄color⁚fg--link: #579dff; + --o⋄color⁚fg--link--visited: #db57ff; + --o⋄color⁚fg--error: #f33; + --o⋄color⁚fg--warning: var(--o⋄color⁚boz__yellow); + --o⋄color⁚fg--info: var(--o⋄color⁚boz__blue); + --o⋄color⁚fg--success: var(--o⋄color⁚boz__green) + } + + [data-o-theme^=dark] { + --o⋄border--thickness: .09rem; + font-weight: 500 + } + + @media (prefers-reduced-motion: reduce) { + *, :before, :after { + scroll-behavior: auto !important; + transition: none .01ms !important; + animation: none !important + } + }:focus { + outline: none + } + + body.user-is-tabbing :focus { + outline: 5px auto var(--o⋄color⁚activity-outline) + } + + button { + touch-action: manipulation; + border-style: solid; + border-color: var(--o⋄color⁚fg--main); + --border--thickness: var(--o⋄border--thickness__button, calc(var(--o⋄border--thickness) * 2)); + border-width: var(--border--thickness); + background-color: var(--o⋄color⁚bg--highlight--1); + color: inherit; + text-align: center; + border-radius: .7em; + margin: .1em; + padding: .3em 2.1em; + text-decoration: none; + display: inline-block + } + + button:hover { + background-color: var(--o⋄color⁚bg--highlight--2) + } + + button:active { + background-color: var(--o⋄color⁚activity-outline) + } + + progress { + --o⋄color⁚progress--bg: var(--o⋄color⁚bg--highlight--1); + --o⋄color⁚progress-border: var(--o⋄color⁚bg--highlight--1); + --o⋄color⁚progress-bar: var(--o⋄color⁚fg--main); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + vertical-align: middle; + background-color: var(--o⋄color⁚progress--bg); + border: solid var(--o⋄border--thickness) var(--o⋄color⁚progress-border); + overflow: hidden + } + + progress::-webkit-progress-bar { + background-color: var(--o⋄color⁚progress--bg) + } + + progress::-webkit-progress-value { + background-color: var(--o⋄color⁚progress-bar) + } + + progress::-moz-progress-bar { + background-color: var(--o⋄color⁚progress-bar) + } + + progress::-ms-fill { + background-color: var(--o⋄color⁚progress-bar); + border: 0 + } + + .o⋄error-report { + color: var(--o⋄color⁚fg--error); + background-color: var(--o⋄color⁚darker--66); + border: 2px dashed var(--o⋄color⁚fg--error); + z-index: 100000; + margin: auto; + padding: .3em; + font-family: monospace; + font-size: xx-small + } + + .o⋄error-report > pre, .o⋄error-report > samp { + white-space: pre-wrap; + text-align: initial + } + + .o⋄border⁚default { + border: solid var(--o⋄border--thickness) var(--o⋄color⁚fg--main) + } + + .o⋄border-colorꘌancillary { + border-color: var(--o⋄color⁚fg--ancillary) + } + + .o⋄colorꘌmain { + color: var(--o⋄color⁚fg--main) + } + + .o⋄colorꘌsecondary { + color: var(--o⋄color⁚fg--secondary) + } + + .o⋄colorꘌancillary { + color: var(--o⋄color⁚fg--ancillary) + } + + .o⋄colorꘌerror { + color: var(--o⋄color⁚fg--error) + } + + .o⋄colorꘌwarning { + color: var(--o⋄color⁚fg--warning) + } + + .o⋄colorꘌinfo { + color: var(--o⋄color⁚fg--info) + } + + .o⋄colorꘌsuccess { + color: var(--o⋄color⁚fg--success) + } + + .o⋄bg-colorꘌmain { + background-color: var(--o⋄color⁚bg--main) + } + + .o⋄bg-colorꘌbackdrop { + background-color: var(--o⋄color⁚bg--main--backdrop) + } + + .o⋄widthꘌ100pc { + width: 100% + } + + .o⋄heightꘌ100pc { + height: 100% + } + + :root { + --o⋄full-viewport__width: 100dvw; + --o⋄full-viewport__height: 100dvh + } + + :has(.o⋄full-viewport), :has(.o⋄usable-viewport) { + border: initial; + margin: 0; + padding: 0 + } + + .o⋄full-viewport, :has(.o⋄usable-viewport) { + max-width: unset; + width: var(--o⋄full-viewport__width); + height: var(--o⋄full-viewport__height); + position: absolute; + top: 0; + left: 0; + overflow: hidden + } + + .o⋄usable-viewport { + top: calc(var(--safe-area-inset-top) + var(--titlebar-area-y) + var(--titlebar-area-height)); + right: var(--safe-area-inset-right); + bottom: var(--safe-area-inset-bottom); + left: var(--safe-area-inset-left); + position: absolute + } + + .o⋄fill-parent { + width: 100%; + height: 100%; + position: absolute; + inset: 0 + } + + .o⋄flex--directionꘌrow { + flex-flow: wrap; + display: flex + } + + .o⋄flex--directionꘌcolumn { + flex-flow: column wrap; + display: flex + } + + .o⋄flex--centered-content { + place-content: center; + align-items: center + } + + .o⋄flex-element--no-grow { + flex-grow: 0 + } + + .o⋄flex-element--grow { + flex-grow: 1 + } + + .o⋄flex-element--no-squish { + flex: none + } + + .o⋄fontꘌfast-and-good-enough { + font-family: var(--o⋄font-family--fast_and_good_enough) + } + + .o⋄fontꘌsystem--sans { + font-family: var(--o⋄font-family--system--sans) + } + + .o⋄fontꘌsystem--serif { + font-family: var(--o⋄font-family--system--serif) + } + + .o⋄fontꘌsystem--mono { + font-family: var(--o⋄font-family--system--mono) + } + + .o⋄text-alignꘌcenter { + text-align: center + } + + .o⋄marginꘌnone { + margin: 0 + } + + .o⋄overflow-yꘌauto { + overflow-y: auto + } + + .o⋄fast-tap { + touch-action: manipulation + } + + .o⋄unstyled { + color: inherit; + outline: inherit; + font: inherit; + cursor: pointer; + background: 0 0; + border: none; + margin: 0; + padding: 0 + } + + .o⋄text-readable-on-any-background { + --color: black; + text-shadow: var(--color) 0px 0px 10px + } + + .o⋄img-visible-on-any-background { + filter: var(--o⋄filter⁚img-visible-on-any-background) + } + + button.o⋄button--inline { + --o⋄border--thickness__button: 0; + border-radius: .35em; + padding: .1em .3em + } + + .o⋄backdrop { + background-color: var(--o⋄color⁚bg--main--backdrop); + backdrop-filter: blur(10px) + } + + .o⋄paddingꘌnone { + padding: 0 + } + + .o⋄paddingꘌsmall { + padding: .3rem + } + + .o⋄paddingꘌmedium { + padding: .7rem + } + + .o⋄positionꘌabsolute { + position: absolute + } + + .o⋄positionꘌrelative { + position: relative + } + + .o⋄positionꘌfixed { + position: fixed + } + + .o⋄rotated⁚45deg { + transform-origin: 50% 50% 0; + display: inline-block; + transform: rotate(45deg) translate(0, 0) + } + + .o⋄rotated⁚90deg { + transform-origin: 50% 50% 0; + display: inline-block; + transform: rotate(90deg) translate(0, 0) + } + + .o⋄rotated⁚180deg { + transform-origin: 50% 50% 0; + display: inline-block; + transform: rotate(180deg) translate(0, 0) + } + + .o⋄rotated⁚270deg { + transform-origin: 50% 50% 0; + display: inline-block; + transform: rotate(270deg) translate(0, 0) + } + + .offirmo--layer--debug { + color: #7cfc00 + } +} diff --git a/stack--current/3-advanced--browser/css--framework/src/advanced/controls.css b/stack--current/3-advanced--browser/css--framework/src/advanced/controls.css index 46cbfb13..6b445e4a 100644 --- a/stack--current/3-advanced--browser/css--framework/src/advanced/controls.css +++ b/stack--current/3-advanced--browser/css--framework/src/advanced/controls.css @@ -23,6 +23,7 @@ body.user-is-tabbing *:focus { * https://fvsch.com/code/styling-buttons/ * TODO https://dbushell.com/2024/03/10/css-button-styles-you-might-not-know/ * TODO https://fdossena.com/?p=html5cool/buttons/i.frag + * TODO move some back to foundation! */ button { touch-action: manipulation; /* we assume PWA, https://webkit.org/blog/5610/more-responsive-tapping-on-ios/ */ diff --git a/stack--current/5-incubator/active/generator--website-entry-points/src/generate--icons/index.ts b/stack--current/5-incubator/active/generator--website-entry-points/src/generate--icons/index.ts index 3a8e5a0a..e6a381e7 100644 --- a/stack--current/5-incubator/active/generator--website-entry-points/src/generate--icons/index.ts +++ b/stack--current/5-incubator/active/generator--website-entry-points/src/generate--icons/index.ts @@ -12,20 +12,28 @@ import { getꓽicon__sizes, getꓽiconⵧemoji, getꓽiconⵧsvg, getꓽicon__pa // null = size-less (true SVG) function generateꓽfile(spec: Immutable, size: number | null): Svg‿str | Buffer { - console.warn(`TODO generate PNG icon!`, { size }) - return 'TODO' + // we need resvg update to support emojis + // we need SVG loading support + // etc. etc. + throw new Error(`NIMP!`) /* if (size === null) { - const svg = getꓽsvg(spec) + const svg = getꓽiconⵧsvg(spec) return svg && getꓽsvg‿str(svg) } if (size === 16) { // TODO .ico + console.warn(`TODO generate .ico file!`, { size }) throw new Error('NIMP!') } + console.warn(`TODO generate icon file!`, { size }) + //throw new Error('TODO REVIEW!') + return 'TODO' + /* const pngⵧbiggest_or_equal = getꓽpng_icon_pathⵧclosest_to_size(spec) + // render to png //console.log(svg) const resvg__opts = { @@ -54,10 +62,13 @@ function generateꓽinline(spec: Immutable): string { ///////////////////////////////////////////////// function generateꓽfixed_sizes(spec: Immutable): EntryPoints { + console.warn(`TODO generate fixed size icon files!`, getꓽicon__sizes(spec)) + return {} + /* return getꓽicon__sizes(spec).reduce((acc, size) => { acc[getꓽicon__path(spec, size)] = generateꓽfile(spec, size) return acc - }, {} as EntryPoints) + }, {} as EntryPoints)*/ } function generate(spec: Immutable): EntryPoints { diff --git a/stack--current/5-incubator/active/interview--plf/package.json b/stack--current/5-incubator/active/interview--plf/package.json index 9834d334..d70b0184 100644 --- a/stack--current/5-incubator/active/interview--plf/package.json +++ b/stack--current/5-incubator/active/interview--plf/package.json @@ -16,13 +16,18 @@ "_build:dev:watch": "monorepo-script--build-typescript-package --watch --module=esm", - "start:parcel": "parcel serve src/index.html --port 8080 --lazy --no-autoinstall", + "serve:parcel": "parcel serve src/index.html --port 8080 --lazy --no-autoinstall", + "serve:serve": "serve --listen 8080 --debug", "dev0": "run-s clean _build:dev:watch", "dev1": "npm-run-all clean start:parcel", - "dev--pub": "ngrok http 8080 --domain=national-rat-supreme.ngrok-free.app" + "dev--pub": "ngrok http 8080 --domain=national-rat-supreme.ngrok-free.app", + + "test": "node --test ./src/" + }, "devDependencies": { + "serve": "^14", "@offirmo-private/monorepo-scripts": "*", "@offirmo-private/toolbox--parcel": "*", "npm-run-all": "^4" diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.nojekyll b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.nojekyll new file mode 100644 index 00000000..91482f00 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.nojekyll @@ -0,0 +1,7 @@ +From GitHub Staff, 2016/11/04 + +If you're not using Jekyll, you can add a .nojekyll file to the root of your repository to disable Jekyll from building your site. Once you do that, your site should build correctly. + +--- +Reason: GitHub build auto-converts the markdown files and don't serve them. +Ref: https://github.com/blog/572-bypassing-jekyll-on-github-pages diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.well-known/security.txt b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.well-known/security.txt new file mode 100644 index 00000000..f7b3bb80 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/.well-known/security.txt @@ -0,0 +1,6 @@ +# https://securitytxt.org/ + +Please report any security issue or danger to the community to: +- https://github.com/Yvem/applied-ai--8ball/issues + +Thanks for your contribution! diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/404.html b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/404.html new file mode 100644 index 00000000..42f96ab2 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/404.html @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + 404 Not Found + + + + + +

404 Not Found

+

Sorry, the page you were looking for doesn't exist.

+ + + + + diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/humans.txt b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/humans.txt new file mode 100644 index 00000000..7ac18ad7 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/humans.txt @@ -0,0 +1,3 @@ +# https://humanstxt.org/ + +This is just a fun website diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/index.css b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/index.css new file mode 100644 index 00000000..e69de29b diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/index.html b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/index.html new file mode 100644 index 00000000..dedcbb4b --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + AI Magic 8 ball + + + + + +
+

🎱AI Magic 8 ball

+ (optional) Please type your question: + + + Answer: +

Traditional: 🎱 + +

+

+ AI: + +

+
+ + + diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/index.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/index.js new file mode 100644 index 00000000..3b768704 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/index.js @@ -0,0 +1,63 @@ + +import { getRandomIntInRange } from './utils/random/index.js' +import { STANDARD_RESPONSES } from './magic8ball/index.js' +import { filter_in_last_quoted_sentence_if_any } from './utils/ai/index.js' + +export default async function main() { + const elt_button_ask = document.getElementById('ask') + const elt_question = document.getElementById('question') + const elt_response_noai = document.getElementById('response-noai') + const elt_response_ai = document.getElementById('response-ai') + + function on_click_ask() { + const { d20, sentence } = get_random_standard_8ball_answer() + console.log({ d20, sentence }) + elt_response_noai.value = sentence + elt_response_ai.value = '(pondering…)' + + const question = (elt_question?.value ?? '').normalize('NFC').trim() + get_response__ai(question, d20) + .then(response => { + console.log({ response }) + elt_response_ai.value = response + }) + .catch(err => { + elt_response_ai.value = `[Internal Error: ${err?.message || 'unknown'}]` + }) + } + + elt_button_ask.onclick = on_click_ask + on_click_ask() +} + +function get_random_standard_8ball_answer() { + const d20 = getRandomIntInRange(1, 20) + const sentence = STANDARD_RESPONSES[d20 - 1] + + return { d20, sentence } +} + +async function get_response__ai(question, d20) { + console.log({ question, d20 }) + + const session = await ai.assistant.create({ + // TODO on day monitor + }) + + const result_raw = await(async () => { + if (d20 <= 10) { + // affirmative + return session.prompt("Generate an affirmative, reassuring prompt to proceed."); + } + else if (d20 <= 15) { + // non-committal + return session.prompt("Generate an excuse saying you'll answer this question later."); + } + else { + // negative + return session.prompt("Generate a gentle but firm prompt to NOT proceed. Make excuses or invoke sources."); + } + })() + + return filter_in_last_quoted_sentence_if_any(result_raw) +} diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/magic8ball/index.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/magic8ball/index.js new file mode 100644 index 00000000..a45a7ebd --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/magic8ball/index.js @@ -0,0 +1,34 @@ +// https://en.wikipedia.org/wiki/Magic_8_Ball + +const STANDARD_RESPONSES_AFFIRMATIVE = [ + 'It is certain', + 'It is decidedly so', + 'Without a doubt', + 'Yes definitely', + 'You may rely on it', + 'As I see it, yes', + 'Most likely', + 'Outlook good', + 'Yes', + 'Signs point to yes', +] +const STANDARD_RESPONSES_NON_COMMITAL = [ + 'Reply hazy, try again', + 'Ask again later', + 'Better not tell you now', + 'Cannot predict now', + 'Concentrate and ask again', +] +const STANDARD_RESPONSES_NEGATIVE = [ + 'Don’t count on it', + 'My reply is no', + 'My sources say no', + 'Outlook not so good', + 'Very doubtful', +] + +export const STANDARD_RESPONSES = [ + ...STANDARD_RESPONSES_AFFIRMATIVE, + ...STANDARD_RESPONSES_NON_COMMITAL, + ...STANDARD_RESPONSES_NEGATIVE, +] diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/index.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/index.js new file mode 100644 index 00000000..5c68aba9 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/index.js @@ -0,0 +1,31 @@ + + + +export function filter_in_last_quoted_sentence_if_any(ai_response) { + ai_response = (ai_response || '').normalize('NFC').trim() + + const splited = ai_response.split('"').map(s => s.trim()).filter(s => !!s) + + if (splited.length > 1) + return splited.at(-1) + + return ai_response +} + + +function clean_ai_response(response) { + console.group('clean_ai_response') + console.log('initial=', response) + response = (response || '').normalize('NFC').trim() + + response = (function pick_last_quote_if_any() { + const splited = response.split('"').map(s => s.trim()).filter(s => !!s) + + if (splited.length > 1) + return splited.at(-1) + })() + + console.log('cleaned=', response) + console.groupEnd() + return response +} diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/test.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/test.js new file mode 100644 index 00000000..1e53546e --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/ai/test.js @@ -0,0 +1,36 @@ +import { describe, it, mock, before, after, beforeEach, afterEach } from 'node:test' // https://devdocs.io/node~20_lts/test +import { strict as assert } from 'node:assert' // https://devdocs.io/node~20_lts/assert +import * as util from 'node:util' + +///////////////////////////////////////////////// + +import { filter_in_last_quoted_sentence_if_any } from './index.js' + +///////////////////////////////////////////////// + +describe('AI utils', () => { + + describe('filter_in_last_quoted_sentence_if_any()', () => { + + it('should work -- actual quote', () => { + const ai_answer = ` Affirmative and Reassuring Prompt: +"Certainly! Go ahead and proceed confidently. Your efforts and hard work will guide you to success."` + const cleaned = filter_in_last_quoted_sentence_if_any(ai_answer) + + assert.deepEqual( + cleaned, + 'Certainly! Go ahead and proceed confidently. Your efforts and hard work will guide you to success.', + ) + }) + + it('should work -- no quote', () => { + const ai_answer = `You should not kill your friend.` + const cleaned = filter_in_last_quoted_sentence_if_any(ai_answer) + + assert.deepEqual( + cleaned, + ai_answer, + ) + }) + }) +}) diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/index.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/index.js new file mode 100644 index 00000000..e564b08b --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/index.js @@ -0,0 +1,15 @@ + +function getRandomU32() { + const randoms = new Uint32Array(1) + crypto.getRandomValues(randoms) + return randoms[0] +} + +export function getRandomIntInRange(min, max, randomU32 = getRandomU32()) { + const range = max - min + 1; + return min + (randomU32 % range); +} + +function getRandomArrayElt(array, randomU32) { + return array[getRandomInt(0, array.length - 1, randomU32)] +} diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/test.js b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/test.js new file mode 100644 index 00000000..91402017 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/js/utils/random/test.js @@ -0,0 +1,29 @@ +import { describe, it, mock, before, after, beforeEach, afterEach } from 'node:test' // https://devdocs.io/node~20_lts/test +import { strict as assert } from 'node:assert' // https://devdocs.io/node~20_lts/assert +import * as util from 'node:util' + +///////////////////////////////////////////////// + +import { getRandomIntInRange } from './index.js' + +///////////////////////////////////////////////// + +describe('Random utils', () => { + + describe('getRandomIntInRange()', () => { + + it('should work', () => { + const distrib = {} + const nb_samples = 1000 + for (let i = 0; i < nb_samples; i++) { + const r = getRandomIntInRange(3, 7) + distrib[r] = (distrib[r] || 0) + 1 + } + + assert.deepEqual( + Object.keys(distrib).sort(), + ['3', '4', '5', '6', '7'], + ) + }) + }) +}) diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/notes.md b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/notes.md new file mode 100644 index 00000000..8b155207 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/notes.md @@ -0,0 +1,56 @@ + +# magic 8 ball + +## research +https://en.wikipedia.org/wiki/Magic_8_Ball +1. 10 affirmatives: + * It is certain + * It is decidedly so + * Without a doubt + * Yes definitely + * You may rely on it + * As I see it, yes + * Most likely + * Outlook good + * Yes + * Signs point to yes +* 5 non-committal: + * Reply hazy, try again + * Ask again later + * Better not tell you now + * Cannot predict now + * Concentrate and ask again +* 5 negative answers + * Don't count on it + * My reply is no + * My sources say no + * Outlook not so good + * Very doubtful + + + +## prompt exploration +https://chrome.dev/web-ai-demos/prompt-api-playground/ + +> Respond with an affirmative answer prompting me to proceed with my idea. + +Generate an affirmative, reassuring statement. +Statement: The outlook is good +Generate an affirmative, reassuring statement. +Statement: Yes definitely +Generate an affirmative, reassuring statement. +Statement: + +You generate affirmative encouragements. + + +> Generate an affirmative, reassuring prompt to proceed. +> Generate an affirmative, reassuring prompt to proceed. You can invoke sources. + +> Generate a gentle but firm prompt to NOT proceed. Make excuses or invoke sources. +> (from ChatGPT, quite funny) Generate a negative, discouraging prompt to proceed. + +> Generate an excuse saying you'll answer this question later. + +#### credits +inspired by https://codepen.io/finnhvman/pen/wrLPJz diff --git a/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/offirmo-framework.css b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/offirmo-framework.css new file mode 100644 index 00000000..b68e9c68 --- /dev/null +++ b/stack--current/5-incubator/active/interview--plf/src/applied-ai--8ball/offirmo-framework.css @@ -0,0 +1 @@ +@layer offirmo--foundation{:root{--o⋄color⁚fg--link--default:#00f;--o⋄color⁚fg--link--visited--default:#531a89;--o⋄color⁚activity-outline--default:#4d91fe;--o⋄color⁚accent--default:#07f;--o⋄font-family--system--sans:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Segoe UI","Helvetica Neue",Helvetica,Cantarell,Ubuntu,Roboto,Noto,Arial,sans-serif;--o⋄font-family--system--mono:ui-monospace,Menlo,Consolas,Monaco,"Liberation Mono","Lucida Console",monospace,monospace;--o⋄font-family--system--serif:ui-serif,"Iowan Old Style","Apple Garamond",Baskerville,"Times New Roman","Droid Serif",Times,"Source Serif Pro",serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}a,svg|a{color:var(--o⋄color⁚fg--link);text-decoration-thickness:var(--o⋄border--thickness);touch-action:manipulation;&:visited{color:var(--o⋄color⁚fg--link--visited)}&:hover{background-color:var(--o⋄color⁚bg--highlight--1)}&:active{color:var(--o⋄color⁚activity-outline)}}blockquote>p:first-of-type:before{content:open-quote}blockquote>p:last-of-type:after{content:close-quote}blockquote>p{display:inline-block}body{max-width:var(--o⋄content-recommended-width);margin:0 max(1ch,(100vw - var(--o⋄content-recommended-width))/2);padding:0}dl{grid-template-columns:max-content 1fr;display:grid}figure{text-align:center;& img{margin:auto}}hr{border:none;border-top:var(--o⋄border--thickness)solid;background-color:var(--o⋄color⁚fg--ancillary);width:100%}iframe{border:0}img{image-orientation:from-image;object-fit:cover;background-color:var(--o⋄color⁚bg--highlight--1);image-rendering:-webkit-optimize-contrast;max-width:100%}nav{& :is(ol,ul){flex-direction:row;gap:2em;padding-inline-start:0;list-style-type:none;display:flex}}p{text-wrap:pretty}strong{color:var(--o⋄color⁚fg--strong)}svg|a{&:link,&:visited{cursor:pointer}&,& text{fill:var(--o⋄color⁚fg--link);text-decoration:underline}&:hover,&:active{outline:dotted var(--o⋄border--thickness)var(--o⋄color⁚activity-outline)}}textarea{form-sizing:normal}details{border:dashed var(--o⋄border--thickness);padding-inline-start:1.4rem}details summary{cursor:pointer;margin-inline-start:-1rem}details summary>*{display:inline}details[open]{border-color:var(--o⋄color⁚fg--main)}:is(h1,h2,h3,h4,h5,h6){color:var(--o⋄color⁚fg--strong);text-wrap:balance;margin-block:.5em}[id]:is(h1,h2,h3,h4,h5,h6){scroll-margin-top:2ex}:root{accent-color:var(--o⋄color⁚accent)}ul,ol{padding-inline-start:1.5em}code,kbd,pre,samp{font-family:var(--o⋄font-family--code);background:var(--o⋄color⁚bg--code);border-radius:.2em;padding-inline:.5ch;font-size:.9em}img,video{max-width:100%;display:block}table{table-layout:fixed;border-collapse:collapse}td{font-variant-numeric:tabular-nums}tbody tr:nth-child(odd){background-color:var(--o⋄color⁚bg--highlight--1)}thead{position:sticky;top:0}:root{scrollbar-color:var(--o⋄color⁚bg--highlight--1)var(--o⋄color⁚bg--main);scrollbar-width:thin}*,:before,:after{scrollbar-color:inherit;scrollbar-width:inherit}::-webkit-scrollbar{xxwidth:.5rem}::-webkit-scrollbar-thumb{background-color:var(--o⋄color⁚bg--highlight--2)}:root{box-sizing:border-box}*,:before,:after{box-sizing:inherit}.box-sizing-reset{box-sizing:initial}:root{color:var(--o⋄color⁚fg--main);background-color:var(--o⋄color⁚bg--main);scroll-behavior:smooth}*{touch-action:manipulation}:root{--o⋄header__scale-ratio:2;font-size:100%}:is(h1,h2,h3,h4){font-size:calc(1rem*(1 + ((var(--o⋄header__scale-ratio) - 1)*var(--o⋄header__scale-ratio__modifier))))}h1{--o⋄header__scale-ratio__modifier:calc(3/3)}h2{--o⋄header__scale-ratio__modifier:calc(2/3)}h3{--o⋄header__scale-ratio__modifier:calc(1/3)}h4{--o⋄header__scale-ratio__modifier:calc(0/3)}small{font-size:.8rem}:root{font-family:var(--o⋄font-family--main);font-variant-numeric:slashed-zero;text-decoration-thickness:var(--o⋄border--thickness);-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;text-rendering:geometricPrecision;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.5}.offirmo--layer--debug{color:#00f}}@layer offirmo--foundation.offirmo--foundation{:root{--o⋄color⁚fg--main:#000;--o⋄color⁚bg--main:#fff;--o⋄color⁚fg--strong:var(--o⋄color⁚fg--main);--o⋄color⁚accent:var(--o⋄color⁚accent--default);--o⋄color⁚fg--link:var(--o⋄color⁚fg--link--default);--o⋄color⁚fg--link--visited:var(--o⋄color⁚fg--link--visited--default);--o⋄color⁚activity-outline:var(--o⋄color⁚activity-outline--default);--o⋄color⁚bg--code:#ededed;--o⋄color⁚bg--highlight--1:#0000001a;--o⋄color⁚bg--highlight--2:#0000004d;--o⋄font-family--fast_and_good_enough:var(--o⋄font-family--system--sans);--o⋄font-family--main:var(--o⋄font-family--fast_and_good_enough);--o⋄font-family--code:var(--o⋄font-family--system--mono);--o⋄border--thickness:.07rem;--o⋄content-recommended-width:60ch}}@layer offirmo--framework{:root{--chromeless-area-inset-top:0px;--chromeless-area-inset-right:0px;--chromeless-area-inset-bottom:0px;--chromeless-area-inset-left:0px;--fold-top:env(fold-top,0px);--fold-right:env(fold-right,0px);--fold-bottom:env(fold-bottom,0px);--fold-left:env(fold-left,0px);--safe-area-inset-top:env(safe-area-inset-top,0px);--safe-area-inset-right:env(safe-area-inset-right,0px);--safe-area-inset-bottom:env(safe-area-inset-bottom,0px);--safe-area-inset-left:env(safe-area-inset-left,0px);--keyboard-inset-top:env(keyboard-inset-top,0px);--keyboard-inset-right:env(keyboard-inset-right,0px);--keyboard-inset-bottom:env(keyboard-inset-bottom,0px);--keyboard-inset-left:env(keyboard-inset-left,0px);--keyboard-inset-width:env(keyboard-inset-width,0px);--keyboard-inset-height:env(keyboard-inset-height,0px);--titlebar-area-x:env(titlebar-area-x,0px);--titlebar-area-y:env(titlebar-area-y,0px);--titlebar-area-width:env(titlebar-area-width,0px);--titlebar-area-height:env(titlebar-area-height,0px);--o⋄min-target-size:36px;--o⋄icon-size--chrome:24px;--o⋄icon-size--tree:20px;--o⋄icon-size--functional:16px;--o⋄margin-from-screen-border--visual:4px;--o⋄margin-from-screen-border--touch:8px}:root{--o⋄color⁚boz__gray:#999;--o⋄color⁚boz__yellow:#f1da32;--o⋄color⁚boz__pink:#f56bcb;--o⋄color⁚boz__green:#94e453;--o⋄color⁚boz__cyan:#1beeee;--o⋄color⁚boz__blue:#34b0ea;--o⋄color⁚boz__purple:#c394f5;--o⋄color⁚darker--10:#0000001a;--o⋄color⁚darker--20:#0003;--o⋄color⁚darker--33:#0005;--o⋄color⁚darker--50:#00000080;--o⋄color⁚darker--66:#000a;--o⋄color⁚darker--90:#000000e6;--o⋄color⁚lighter--10:#ffffff1a;--o⋄color⁚lighter--20:#fff3;--o⋄color⁚lighter--33:#fff5;--o⋄color⁚lighter--66:#fffa;--o⋄color⁚lighter--90:#ffffffe6}[data-o-theme],.o⋄error-report{color:var(--o⋄color⁚fg--main);background-color:var(--o⋄color⁚bg--main);accent-color:var(--o⋄color⁚accent);scrollbar-color:var(--o⋄color⁚bg--highlight--1)var(--o⋄color⁚bg--main)}:root:not([data-o-theme]),[data-o-theme^=light]{--o⋄color⁚fg--main:black;--o⋄color⁚fg--secondary:oklch(from var(--o⋄color⁚fg--main)l c h/66%);--o⋄color⁚fg--ancillary:oklch(from var(--o⋄color⁚fg--main)l c h/33%);--o⋄color⁚fg--strong:var(--o⋄color⁚fg--main);--o⋄color⁚bg--main:white;--o⋄color⁚bg--code:#e6e6e6;--o⋄color⁚bg--main--backdrop:var(--o⋄color⁚darker--66);--o⋄color⁚bg--highlight--1:var(--o⋄color⁚darker--10);--o⋄color⁚bg--highlight--2:var(--o⋄color⁚darker--33);--o⋄color⁚accent:var(--o⋄color⁚accent--default);--o⋄color⁚activity-outline:var(--o⋄color⁚activity-outline--default);--o⋄color⁚fg--link:var(--o⋄color⁚fg--link--default);--o⋄color⁚fg--link--visited:var(--o⋄color⁚fg--link--visited--default);--o⋄color⁚fg--error:#e50000;--o⋄color⁚fg--warning:#990;--o⋄color⁚fg--info:#00a6b2;--o⋄color⁚fg--success:#00a600}[data-o-theme^=dark],.o⋄error-report{--o⋄color⁚fg--main:white;--o⋄color⁚fg--secondary:oklch(from var(--o⋄color⁚fg--main)l c h/66%);--o⋄color⁚fg--ancillary:oklch(from var(--o⋄color⁚fg--main)l c h/33%);--o⋄color⁚fg--strong:var(--o⋄color⁚fg--main);--o⋄color⁚bg--main:black;--o⋄color⁚bg--code:#404040;--o⋄color⁚bg--main--backdrop:var(--o⋄color⁚darker--66);--o⋄color⁚bg--highlight--1:var(--o⋄color⁚lighter--20);--o⋄color⁚bg--highlight--2:var(--o⋄color⁚lighter--33);--o⋄color⁚accent:var(--o⋄color⁚accent--default);--o⋄color⁚activity-outline:var(--o⋄color⁚activity-outline--default);--o⋄color⁚fg--link:#579dff;--o⋄color⁚fg--link--visited:#db57ff;--o⋄color⁚fg--error:#f33;--o⋄color⁚fg--warning:var(--o⋄color⁚boz__yellow);--o⋄color⁚fg--info:var(--o⋄color⁚boz__blue);--o⋄color⁚fg--success:var(--o⋄color⁚boz__green)}[data-o-theme^=dark]{--o⋄border--thickness:.09rem;font-weight:500}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition:none .01ms!important;animation:none!important}}:focus{outline:none}body.user-is-tabbing :focus{outline:5px auto var(--o⋄color⁚activity-outline)}button{touch-action:manipulation;border-style:solid;border-color:var(--o⋄color⁚fg--main);--border--thickness:var(--o⋄border--thickness__button,calc(var(--o⋄border--thickness)*2));border-width:var(--border--thickness);background-color:var(--o⋄color⁚bg--highlight--1);color:inherit;text-align:center;border-radius:.7em;margin:.1em;padding:.3em 2.1em;text-decoration:none;display:inline-block}button:hover{background-color:var(--o⋄color⁚bg--highlight--2)}button:active{background-color:var(--o⋄color⁚activity-outline)}progress{--o⋄color⁚progress--bg:var(--o⋄color⁚bg--highlight--1);--o⋄color⁚progress-border:var(--o⋄color⁚bg--highlight--1);--o⋄color⁚progress-bar:var(--o⋄color⁚fg--main);-webkit-appearance:none;-moz-appearance:none;appearance:none;vertical-align:middle;background-color:var(--o⋄color⁚progress--bg);border:solid var(--o⋄border--thickness)var(--o⋄color⁚progress-border);overflow:hidden}progress::-webkit-progress-bar{background-color:var(--o⋄color⁚progress--bg)}progress::-webkit-progress-value{background-color:var(--o⋄color⁚progress-bar)}progress::-moz-progress-bar{background-color:var(--o⋄color⁚progress-bar)}progress::-ms-fill{background-color:var(--o⋄color⁚progress-bar);border:0}.o⋄error-report{color:var(--o⋄color⁚fg--error);background-color:var(--o⋄color⁚darker--66);border:2px dashed var(--o⋄color⁚fg--error);z-index:100000;margin:auto;padding:.3em;font-family:monospace;font-size:xx-small}.o⋄error-report>pre,.o⋄error-report>samp{white-space:pre-wrap;text-align:initial}.o⋄border⁚default{border:solid var(--o⋄border--thickness)var(--o⋄color⁚fg--main)}.o⋄border-colorꘌancillary{border-color:var(--o⋄color⁚fg--ancillary)}.o⋄colorꘌmain{color:var(--o⋄color⁚fg--main)}.o⋄colorꘌsecondary{color:var(--o⋄color⁚fg--secondary)}.o⋄colorꘌancillary{color:var(--o⋄color⁚fg--ancillary)}.o⋄colorꘌerror{color:var(--o⋄color⁚fg--error)}.o⋄colorꘌwarning{color:var(--o⋄color⁚fg--warning)}.o⋄colorꘌinfo{color:var(--o⋄color⁚fg--info)}.o⋄colorꘌsuccess{color:var(--o⋄color⁚fg--success)}.o⋄bg-colorꘌmain{background-color:var(--o⋄color⁚bg--main)}.o⋄bg-colorꘌbackdrop{background-color:var(--o⋄color⁚bg--main--backdrop)}.o⋄widthꘌ100pc{width:100%}.o⋄heightꘌ100pc{height:100%}:root{--o⋄full-viewport__width:100dvw;--o⋄full-viewport__height:100dvh}:has(.o⋄full-viewport),:has(.o⋄usable-viewport){border:initial;margin:0;padding:0}.o⋄full-viewport,:has(.o⋄usable-viewport){max-width:unset;width:var(--o⋄full-viewport__width);height:var(--o⋄full-viewport__height);position:absolute;top:0;left:0;overflow:hidden}.o⋄usable-viewport{top:calc(var(--safe-area-inset-top) + var(--titlebar-area-y) + var(--titlebar-area-height));right:var(--safe-area-inset-right);bottom:var(--safe-area-inset-bottom);left:var(--safe-area-inset-left);position:absolute}.o⋄fill-parent{width:100%;height:100%;position:absolute;inset:0}.o⋄flex--directionꘌrow{flex-flow:wrap;display:flex}.o⋄flex--directionꘌcolumn{flex-flow:column wrap;display:flex}.o⋄flex--centered-content{place-content:center;align-items:center}.o⋄flex-element--no-grow{flex-grow:0}.o⋄flex-element--grow{flex-grow:1}.o⋄flex-element--no-squish{flex:none}.o⋄fontꘌfast-and-good-enough{font-family:var(--o⋄font-family--fast_and_good_enough)}.o⋄fontꘌsystem--sans{font-family:var(--o⋄font-family--system--sans)}.o⋄fontꘌsystem--serif{font-family:var(--o⋄font-family--system--serif)}.o⋄fontꘌsystem--mono{font-family:var(--o⋄font-family--system--mono)}.o⋄text-alignꘌcenter{text-align:center}.o⋄marginꘌnone{margin:0}.o⋄overflow-yꘌauto{overflow-y:auto}.o⋄fast-tap{touch-action:manipulation}.o⋄unstyled{color:inherit;outline:inherit;font:inherit;cursor:pointer;background:0 0;border:none;margin:0;padding:0}.o⋄text-readable-on-any-background{--color:black;text-shadow:var(--color)0px 0px 10px}.o⋄img-visible-on-any-background{filter:var(--o⋄filter⁚img-visible-on-any-background)}button.o⋄button--inline{--o⋄border--thickness__button:0;border-radius:.35em;padding:.1em .3em}.o⋄backdrop{background-color:var(--o⋄color⁚bg--main--backdrop);backdrop-filter:blur(10px)}.o⋄paddingꘌnone{padding:0}.o⋄paddingꘌsmall{padding:.3rem}.o⋄paddingꘌmedium{padding:.7rem}.o⋄positionꘌabsolute{position:absolute}.o⋄positionꘌrelative{position:relative}.o⋄positionꘌfixed{position:fixed}.o⋄rotated⁚45deg{transform-origin:50% 50% 0;display:inline-block;transform:rotate(45deg)translate(0,0)}.o⋄rotated⁚90deg{transform-origin:50% 50% 0;display:inline-block;transform:rotate(90deg)translate(0,0)}.o⋄rotated⁚180deg{transform-origin:50% 50% 0;display:inline-block;transform:rotate(180deg)translate(0,0)}.o⋄rotated⁚270deg{transform-origin:50% 50% 0;display:inline-block;transform:rotate(270deg)translate(0,0)}.offirmo--layer--debug{color:#7cfc00}} \ No newline at end of file diff --git a/stack--current/5-incubator/active/interview--plf/src/chrome-ai/index.mjs b/stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/index.mjs similarity index 73% rename from stack--current/5-incubator/active/interview--plf/src/chrome-ai/index.mjs rename to stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/index.mjs index 4423e7c1..31303c23 100644 --- a/stack--current/5-incubator/active/interview--plf/src/chrome-ai/index.mjs +++ b/stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/index.mjs @@ -1,5 +1,6 @@ + async function demo__assistant() { const session = await ai.assistant.create({ monitor(m) { @@ -15,6 +16,30 @@ async function demo__assistant() { } +async function demo__8ball() { + const session = await ai.assistant.create({ + systemPrompt: "You're a magic 8 ball. You reply to questions by an affirmative, a negative or a non-committal.", + } + ) + + const stream = session.promptStreaming("Should I do it?"); + /* + for await (const chunk of stream) { + console.log(chunk); + }*/ + let result = ''; + let previousLength = 0; + for await (const chunk of stream) { + const newContent = chunk.slice(previousLength); + console.log(newContent); + previousLength = chunk.length; + result += newContent; + } + //console.log(result); + +} + + export default async function main() { let innerHTML = '' @@ -22,6 +47,7 @@ export default async function main() { console.group('AI detection') if (!globalThis.ai) { const err = new Error(`AI feature not available! Please follow https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit#heading=h.witohboigk0o`) + throw err } innerHTML += `
  1. [globalThis.]ai API detected ✅
  2. ` console.log({ai}) @@ -48,8 +74,11 @@ export default async function main() { innerHTML += `
  3. demo:` switch (sub_api) { case 'assistant': + innerHTML += ` chrome.dev↗` + break + /*case 'assistant': innerHTML += `
    ` - demo__assistant() + /*demo__assistant() .then(result => { const elt = document.getElementById(`demo__${sub_api}`) elt.innerHTML = result @@ -59,6 +88,7 @@ export default async function main() { const elt = document.getElementById(`demo__${sub_api}`) elt.innerHTML = `Error: ${err?.message}` }) + */ break default: innerHTML += ` (no demo for this API)` @@ -70,6 +100,7 @@ export default async function main() { console.groupEnd() } innerHTML += `
  4. ` + demo__8ball() } catch (err) { console.error(err, {err}) @@ -79,5 +110,6 @@ export default async function main() { const div = document.createElement('div') div.innerHTML = innerHTML document.body.appendChild(div) + console.groupEnd() } } diff --git a/stack--current/5-incubator/active/interview--plf/src/chrome-ai/notes.md b/stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/notes.md similarity index 81% rename from stack--current/5-incubator/active/interview--plf/src/chrome-ai/notes.md rename to stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/notes.md index 61552708..34d425f3 100644 --- a/stack--current/5-incubator/active/interview--plf/src/chrome-ai/notes.md +++ b/stack--current/5-incubator/active/interview--plf/src/chrome-ai--discovery/notes.md @@ -13,7 +13,9 @@ Demo https://chrome.dev/web-ai-demos/prompt-api-playground/ -Explainer https://github.com/explainers-by-googlers/prompt-api/ +Explainers +* prompt API https://github.com/explainers-by-googlers/prompt-api/ +* Web Translation and Language Detection APIs https://github.com/WICG/translation-api Concepts: * Origin trials @@ -26,3 +28,9 @@ Install 1. download chrome://components/ 1. download live 1. test https://chrome.dev/web-ai-demos/prompt-api-playground/ + + + + +#### prompt exploration +https://chrome.dev/web-ai-demos/prompt-api-playground/ diff --git a/stack--current/5-incubator/active/interview--plf/src/index.html b/stack--current/5-incubator/active/interview--plf/src/index.html index dd8f2ea4..3188eb34 100644 --- a/stack--current/5-incubator/active/interview--plf/src/index.html +++ b/stack--current/5-incubator/active/interview--plf/src/index.html @@ -1,32 +1,29 @@ -

    Hello, world!

    - - +

    Loading...

    +