diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..3a632220 --- /dev/null +++ b/404.html @@ -0,0 +1,1269 @@ + + + + + + + + + + + + + + + + + + + RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/assets/5_porques.png b/assets/5_porques.png new file mode 100644 index 00000000..98b71e1c Binary files /dev/null and b/assets/5_porques.png differ diff --git a/assets/ERprocess.png b/assets/ERprocess.png new file mode 100644 index 00000000..1b0535b2 Binary files /dev/null and b/assets/ERprocess.png differ diff --git a/assets/Github_Icon.png b/assets/Github_Icon.png new file mode 100644 index 00000000..9490ffc6 Binary files /dev/null and b/assets/Github_Icon.png differ diff --git a/assets/GoogleMeet_Icon.png b/assets/GoogleMeet_Icon.png new file mode 100644 index 00000000..f6cde5e4 Binary files /dev/null and b/assets/GoogleMeet_Icon.png differ diff --git a/assets/MatrizRiscos.png b/assets/MatrizRiscos.png new file mode 100644 index 00000000..0a8d95f3 Binary files /dev/null and b/assets/MatrizRiscos.png differ diff --git a/assets/brasao.jpg b/assets/brasao.jpg new file mode 100644 index 00000000..c31bc9fa Binary files /dev/null and b/assets/brasao.jpg differ diff --git a/assets/eap.jpeg b/assets/eap.jpeg new file mode 100644 index 00000000..2e9a897c Binary files /dev/null and b/assets/eap.jpeg differ diff --git a/assets/facetas_engenharia.png b/assets/facetas_engenharia.png new file mode 100644 index 00000000..50a98ead Binary files /dev/null and b/assets/facetas_engenharia.png differ diff --git a/assets/gitflow.png b/assets/gitflow.png new file mode 100644 index 00000000..aaa8e2ff Binary files /dev/null and b/assets/gitflow.png differ diff --git a/assets/gupta1.png b/assets/gupta1.png new file mode 100644 index 00000000..ddf01330 Binary files /dev/null and b/assets/gupta1.png differ diff --git a/assets/gupta2.png b/assets/gupta2.png new file mode 100644 index 00000000..df62b5d7 Binary files /dev/null and b/assets/gupta2.png differ diff --git a/assets/gupta3.png b/assets/gupta3.png new file mode 100644 index 00000000..2e42d59b Binary files /dev/null and b/assets/gupta3.png differ diff --git a/assets/gupta4.png b/assets/gupta4.png new file mode 100644 index 00000000..e73d1e81 Binary files /dev/null and b/assets/gupta4.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000..1cf13b9f Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.56dfad97.min.js b/assets/javascripts/bundle.56dfad97.min.js new file mode 100644 index 00000000..1df62cd7 --- /dev/null +++ b/assets/javascripts/bundle.56dfad97.min.js @@ -0,0 +1,16 @@ +"use strict";(()=>{var Fi=Object.create;var gr=Object.defineProperty;var Wi=Object.getOwnPropertyDescriptor;var Ui=Object.getOwnPropertyNames,Vt=Object.getOwnPropertySymbols,Di=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,io=Object.prototype.propertyIsEnumerable;var no=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,$=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&no(e,r,t[r]);if(Vt)for(var r of Vt(t))io.call(t,r)&&no(e,r,t[r]);return e};var ao=(e,t)=>{var r={};for(var o in e)yr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Vt)for(var o of Vt(e))t.indexOf(o)<0&&io.call(e,o)&&(r[o]=e[o]);return r};var xr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Vi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ui(t))!yr.call(e,n)&&n!==r&&gr(e,n,{get:()=>t[n],enumerable:!(o=Wi(t,n))||o.enumerable});return e};var Lt=(e,t,r)=>(r=e!=null?Fi(Di(e)):{},Vi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var so=(e,t,r)=>new Promise((o,n)=>{var i=p=>{try{s(r.next(p))}catch(c){n(c)}},a=p=>{try{s(r.throw(p))}catch(c){n(c)}},s=p=>p.done?o(p.value):Promise.resolve(p.value).then(i,a);s((r=r.apply(e,t)).next())});var po=xr((Er,co)=>{(function(e,t){typeof Er=="object"&&typeof co!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Er,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(k){return!!(k&&k!==document&&k.nodeName!=="HTML"&&k.nodeName!=="BODY"&&"classList"in k&&"contains"in k.classList)}function p(k){var ft=k.type,qe=k.tagName;return!!(qe==="INPUT"&&a[ft]&&!k.readOnly||qe==="TEXTAREA"&&!k.readOnly||k.isContentEditable)}function c(k){k.classList.contains("focus-visible")||(k.classList.add("focus-visible"),k.setAttribute("data-focus-visible-added",""))}function l(k){k.hasAttribute("data-focus-visible-added")&&(k.classList.remove("focus-visible"),k.removeAttribute("data-focus-visible-added"))}function f(k){k.metaKey||k.altKey||k.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(k){o=!1}function d(k){s(k.target)&&(o||p(k.target))&&c(k.target)}function y(k){s(k.target)&&(k.target.classList.contains("focus-visible")||k.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(k.target))}function M(k){document.visibilityState==="hidden"&&(n&&(o=!0),X())}function X(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(k){k.target.nodeName&&k.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",M,!0),X(),r.addEventListener("focus",d,!0),r.addEventListener("blur",y,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var qr=xr((ly,Sn)=>{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ka=/["'&<>]/;Sn.exports=Ha;function Ha(e){var t=""+e,r=ka.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof It=="object"&&typeof Yr=="object"?Yr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof It=="object"?It.ClipboardJS=r():t.ClipboardJS=r()})(It,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return ji}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(V){try{return document.execCommand(V)}catch(A){return!1}}var d=function(A){var L=f()(A);return u("cut"),L},y=d;function M(V){var A=document.documentElement.getAttribute("dir")==="rtl",L=document.createElement("textarea");L.style.fontSize="12pt",L.style.border="0",L.style.padding="0",L.style.margin="0",L.style.position="absolute",L.style[A?"right":"left"]="-9999px";var F=window.pageYOffset||document.documentElement.scrollTop;return L.style.top="".concat(F,"px"),L.setAttribute("readonly",""),L.value=V,L}var X=function(A,L){var F=M(A);L.container.appendChild(F);var D=f()(F);return u("copy"),F.remove(),D},te=function(A){var L=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},F="";return typeof A=="string"?F=X(A,L):A instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(A==null?void 0:A.type)?F=X(A.value,L):(F=f()(A),u("copy")),F},J=te;function k(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?k=function(L){return typeof L}:k=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},k(V)}var ft=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},L=A.action,F=L===void 0?"copy":L,D=A.container,Y=A.target,$e=A.text;if(F!=="copy"&&F!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&k(Y)==="object"&&Y.nodeType===1){if(F==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(F==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if($e)return J($e,{container:D});if(Y)return F==="cut"?y(Y):J(Y,{container:D})},qe=ft;function Fe(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Fe=function(L){return typeof L}:Fe=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},Fe(V)}function Ai(V,A){if(!(V instanceof A))throw new TypeError("Cannot call a class as a function")}function oo(V,A){for(var L=0;L0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof D.action=="function"?D.action:this.defaultAction,this.target=typeof D.target=="function"?D.target:this.defaultTarget,this.text=typeof D.text=="function"?D.text:this.defaultText,this.container=Fe(D.container)==="object"?D.container:document.body}},{key:"listenClick",value:function(D){var Y=this;this.listener=c()(D,"click",function($e){return Y.onClick($e)})}},{key:"onClick",value:function(D){var Y=D.delegateTarget||D.currentTarget,$e=this.action(Y)||"copy",Dt=qe({action:$e,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Dt?"success":"error",{action:$e,text:Dt,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(D){return vr("action",D)}},{key:"defaultTarget",value:function(D){var Y=vr("target",D);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(D){return vr("text",D)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(D){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(D,Y)}},{key:"cut",value:function(D){return y(D)}},{key:"isSupported",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof D=="string"?[D]:D,$e=!!document.queryCommandSupported;return Y.forEach(function(Dt){$e=$e&&!!document.queryCommandSupported(Dt)}),$e}}]),L}(s()),ji=Ii},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,d,y){var M=c.apply(this,arguments);return l.addEventListener(u,M,y),{destroy:function(){l.removeEventListener(u,M,y)}}}function p(l,f,u,d,y){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(M){return s(M,f,u,d,y)}))}function c(l,f,u,d){return function(y){y.delegateTarget=a(y.target,f),y.delegateTarget&&d.call(l,y)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,d,y){if(!u&&!d&&!y)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(y))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,d,y);if(a.nodeList(u))return l(u,d,y);if(a.string(u))return f(u,d,y);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,d,y){return u.addEventListener(d,y),{destroy:function(){u.removeEventListener(d,y)}}}function l(u,d,y){return Array.prototype.forEach.call(u,function(M){M.addEventListener(d,y)}),{destroy:function(){Array.prototype.forEach.call(u,function(M){M.removeEventListener(d,y)})}}}function f(u,d,y){return s(document.body,u,d,y)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||p(d,M)})},y&&(n[d]=y(n[d])))}function p(d,y){try{c(o[d](y))}catch(M){u(i[0][3],M)}}function c(d){d.value instanceof nt?Promise.resolve(d.value.v).then(l,f):u(i[0][2],d)}function l(d){p("next",d)}function f(d){p("throw",d)}function u(d,y){d(y),i.shift(),i.length&&p(i[0][0],i[0][1])}}function fo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof he=="function"?he(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function H(e){return typeof e=="function"}function ut(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var zt=ut(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Qe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var We=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=he(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(M){t={error:M}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(H(l))try{l()}catch(M){i=M instanceof zt?M.errors:[M]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=he(f),d=u.next();!d.done;d=u.next()){var y=d.value;try{uo(y)}catch(M){i=i!=null?i:[],M instanceof zt?i=q(q([],N(i)),N(M.errors)):i.push(M)}}}catch(M){o={error:M}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new zt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)uo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Qe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Qe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=We.EMPTY;function qt(e){return e instanceof We||e&&"closed"in e&&H(e.remove)&&H(e.add)&&H(e.unsubscribe)}function uo(e){H(e)?e():e.unsubscribe()}var Pe={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var dt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new We(function(){o.currentObservers=null,Qe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new wo(r,o)},t}(j);var wo=function(e){oe(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Tr},t}(g);var _r=function(e){oe(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(g);var At={now:function(){return(At.delegate||Date).now()},delegate:void 0};var Ct=function(e){oe(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=At);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(gt);var Oo=function(e){oe(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(yt);var kr=new Oo(So);var Mo=function(e){oe(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=vt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(vt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(gt);var Lo=function(e){oe(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(yt);var me=new Lo(Mo);var S=new j(function(e){return e.complete()});function Yt(e){return e&&H(e.schedule)}function Hr(e){return e[e.length-1]}function Xe(e){return H(Hr(e))?e.pop():void 0}function ke(e){return Yt(Hr(e))?e.pop():void 0}function Bt(e,t){return typeof Hr(e)=="number"?e.pop():t}var xt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Gt(e){return H(e==null?void 0:e.then)}function Jt(e){return H(e[bt])}function Xt(e){return Symbol.asyncIterator&&H(e==null?void 0:e[Symbol.asyncIterator])}function Zt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ji(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var er=Ji();function tr(e){return H(e==null?void 0:e[er])}function rr(e){return mo(this,arguments,function(){var r,o,n,i;return Nt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,nt(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,nt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,nt(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function or(e){return H(e==null?void 0:e.getReader)}function W(e){if(e instanceof j)return e;if(e!=null){if(Jt(e))return Xi(e);if(xt(e))return Zi(e);if(Gt(e))return ea(e);if(Xt(e))return _o(e);if(tr(e))return ta(e);if(or(e))return ra(e)}throw Zt(e)}function Xi(e){return new j(function(t){var r=e[bt]();if(H(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Zi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?b(function(n,i){return e(n,i,o)}):le,Te(1),r?De(t):qo(function(){return new ir}))}}function jr(e){return e<=0?function(){return S}:E(function(t,r){var o=[];t.subscribe(T(r,function(n){o.push(n),e=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,d=0,y=!1,M=!1,X=function(){f==null||f.unsubscribe(),f=void 0},te=function(){X(),l=u=void 0,y=M=!1},J=function(){var k=l;te(),k==null||k.unsubscribe()};return E(function(k,ft){d++,!M&&!y&&X();var qe=u=u!=null?u:r();ft.add(function(){d--,d===0&&!M&&!y&&(f=Wr(J,p))}),qe.subscribe(ft),!l&&d>0&&(l=new at({next:function(Fe){return qe.next(Fe)},error:function(Fe){M=!0,X(),f=Wr(te,n,Fe),qe.error(Fe)},complete:function(){y=!0,X(),f=Wr(te,a),qe.complete()}}),W(k).subscribe(l))})(c)}}function Wr(e,t){for(var r=[],o=2;oe.next(document)),e}function P(e,t=document){return Array.from(t.querySelectorAll(e))}function R(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ie(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var xa=O(h(document.body,"focusin"),h(document.body,"focusout")).pipe(_e(1),Q(void 0),m(()=>Ie()||document.body),G(1));function et(e){return xa.pipe(m(t=>e.contains(t)),K())}function $t(e,t){return C(()=>O(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ht(r=>Me(+!r*t)):le,Q(e.matches(":hover"))))}function Go(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Go(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Go(o,n);return o}function sr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function Tt(e){let t=x("script",{src:e});return C(()=>(document.head.appendChild(t),O(h(t,"load"),h(t,"error").pipe(v(()=>$r(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),Te(1))))}var Jo=new g,Ea=C(()=>typeof ResizeObserver=="undefined"?Tt("https://unpkg.com/resize-observer-polyfill"):I(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>Jo.next(t)))),v(e=>O(Ye,I(e)).pipe(_(()=>e.disconnect()))),G(1));function ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return Ea.pipe(w(r=>r.observe(t)),v(r=>Jo.pipe(b(o=>o.target===t),_(()=>r.unobserve(t)))),m(()=>ce(e)),Q(ce(e)))}function St(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function Xo(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Ve(e){return{x:e.offsetLeft,y:e.offsetTop}}function Zo(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function en(e){return O(h(window,"load"),h(window,"resize")).pipe(Le(0,me),m(()=>Ve(e)),Q(Ve(e)))}function pr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ne(e){return O(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe(Le(0,me),m(()=>pr(e)),Q(pr(e)))}var tn=new g,wa=C(()=>I(new IntersectionObserver(e=>{for(let t of e)tn.next(t)},{threshold:0}))).pipe(v(e=>O(Ye,I(e)).pipe(_(()=>e.disconnect()))),G(1));function tt(e){return wa.pipe(w(t=>t.observe(e)),v(t=>tn.pipe(b(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function rn(e,t=16){return Ne(e).pipe(m(({y:r})=>{let o=ce(e),n=St(e);return r>=n.height-o.height-t}),K())}var lr={drawer:R("[data-md-toggle=drawer]"),search:R("[data-md-toggle=search]")};function on(e){return lr[e].checked}function Je(e,t){lr[e].checked!==t&&lr[e].click()}function ze(e){let t=lr[e];return h(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function Ta(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Sa(){return O(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function nn(){let e=h(window,"keydown").pipe(b(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:on("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),b(({mode:t,type:r})=>{if(t==="global"){let o=Ie();if(typeof o!="undefined")return!Ta(o,r)}return!0}),pe());return Sa().pipe(v(t=>t?S:e))}function ye(){return new URL(location.href)}function lt(e,t=!1){if(B("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function an(){return new g}function sn(){return location.hash.slice(1)}function cn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Oa(e){return O(h(window,"hashchange"),e).pipe(m(sn),Q(sn()),b(t=>t.length>0),G(1))}function pn(e){return Oa(e).pipe(m(t=>fe(`[id="${t}"]`)),b(t=>typeof t!="undefined"))}function Pt(e){let t=matchMedia(e);return ar(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function ln(){let e=matchMedia("print");return O(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function Nr(e,t){return e.pipe(v(r=>r?t():S))}function zr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function je(e,t){return zr(e,t).pipe(v(r=>r.text()),m(r=>JSON.parse(r)),G(1))}function mn(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),G(1))}function fn(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),G(1))}function un(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function dn(){return O(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(un),Q(un()))}function hn(){return{width:innerWidth,height:innerHeight}}function bn(){return h(window,"resize",{passive:!0}).pipe(m(hn),Q(hn()))}function vn(){return z([dn(),bn()]).pipe(m(([e,t])=>({offset:e,size:t})),G(1))}function mr(e,{viewport$:t,header$:r}){let o=t.pipe(ee("size")),n=z([o,r]).pipe(m(()=>Ve(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function Ma(e){return h(e,"message",t=>t.data)}function La(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function gn(e,t=new Worker(e)){let r=Ma(t),o=La(t),n=new g;n.subscribe(o);let i=o.pipe(Z(),ie(!0));return n.pipe(Z(),Re(r.pipe(U(i))),pe())}var _a=R("#__config"),Ot=JSON.parse(_a.textContent);Ot.base=`${new URL(Ot.base,ye())}`;function xe(){return Ot}function B(e){return Ot.features.includes(e)}function Ee(e,t){return typeof t!="undefined"?Ot.translations[e].replace("#",t.toString()):Ot.translations[e]}function Se(e,t=document){return R(`[data-md-component=${e}]`,t)}function ae(e,t=document){return P(`[data-md-component=${e}]`,t)}function Aa(e){let t=R(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>R(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function yn(e){if(!B("announce.dismiss")||!e.childElementCount)return S;if(!e.hidden){let t=R(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return C(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Aa(e).pipe(w(r=>t.next(r)),_(()=>t.complete()),m(r=>$({ref:e},r)))})}function Ca(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function xn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),Ca(e,t).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))}function Rt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function En(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function wn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Rt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Rt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function Tn(e){return x("button",{class:"md-clipboard md-icon",title:Ee("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}var On=Lt(qr());function Qr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,x("del",null,(0,On.default)(c))," "],[]).slice(0,-1),i=xe(),a=new URL(e.location,i.base);B("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=xe();return x("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Ee("search.result.term.missing"),": ",...n)))}function Mn(e){let t=e[0].score,r=[...e],o=xe(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreQr(l,1)),...p.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,p.length>0&&p.length===1?Ee("search.result.more.one"):Ee("search.result.more.other",p.length))),...p.map(l=>Qr(l,1)))]:[]];return x("li",{class:"md-search-result__item"},c)}function Ln(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?sr(r):r)))}function Kr(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function _n(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function $a(e){var o;let t=xe(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function An(e,t){var o;let r=xe();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Ee("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map($a)))}var Pa=0;function Ra(e){let t=z([et(e),$t(e)]).pipe(m(([o,n])=>o||n),K()),r=C(()=>Xo(e)).pipe(ne(Ne),pt(1),He(t),m(()=>Zo(e)));return t.pipe(Ae(o=>o),v(()=>z([t,r])),m(([o,n])=>({active:o,offset:n})),pe())}function Ia(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Pa++}`;return C(()=>{let i=new g,a=new _r(!1);i.pipe(Z(),ie(!1)).subscribe(a);let s=a.pipe(Ht(c=>Me(+!c*250,kr)),K(),v(c=>c?r:S),w(c=>c.id=n),pe());z([i.pipe(m(({active:c})=>c)),s.pipe(v(c=>$t(c,250)),Q(!1))]).pipe(m(c=>c.some(l=>l))).subscribe(a);let p=a.pipe(b(c=>c),re(s,o),m(([c,l,{size:f}])=>{let u=e.getBoundingClientRect(),d=u.width/2;if(l.role==="tooltip")return{x:d,y:8+u.height};if(u.y>=f.height/2){let{height:y}=ce(l);return{x:d,y:-16-y}}else return{x:d,y:16+u.height}}));return z([s,i,p]).subscribe(([c,{offset:l},f])=>{c.style.setProperty("--md-tooltip-host-x",`${l.x}px`),c.style.setProperty("--md-tooltip-host-y",`${l.y}px`),c.style.setProperty("--md-tooltip-x",`${f.x}px`),c.style.setProperty("--md-tooltip-y",`${f.y}px`),c.classList.toggle("md-tooltip2--top",f.y<0),c.classList.toggle("md-tooltip2--bottom",f.y>=0)}),a.pipe(b(c=>c),re(s,(c,l)=>l),b(c=>c.role==="tooltip")).subscribe(c=>{let l=ce(R(":scope > *",c));c.style.setProperty("--md-tooltip-width",`${l.width}px`),c.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(K(),ve(me),re(s)).subscribe(([c,l])=>{l.classList.toggle("md-tooltip2--active",c)}),z([a.pipe(b(c=>c)),s]).subscribe(([c,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),a.pipe(b(c=>!c)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Ra(e).pipe(w(c=>i.next(c)),_(()=>i.complete()),m(c=>$({ref:e},c)))})}function mt(e,{viewport$:t},r=document.body){return Ia(e,{content$:new j(o=>{let n=e.title,i=En(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t})}function ja(e,t){let r=C(()=>z([en(e),Ne(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ce(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return et(e).pipe(v(o=>r.pipe(m(n=>({active:o,offset:n})),Te(+!o||1/0))))}function Cn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return C(()=>{let i=new g,a=i.pipe(Z(),ie(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),tt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),O(i.pipe(b(({active:s})=>s)),i.pipe(_e(250),b(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Le(16,me)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(pt(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(U(a),b(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),h(n,"mousedown").pipe(U(a),re(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Ie())==null||c.blur()}}),r.pipe(U(a),b(s=>s===o),Ge(125)).subscribe(()=>e.focus()),ja(e,t).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))})}function Fa(e){return e.tagName==="CODE"?P(".c, .c1, .cm",e):[e]}function Wa(e){let t=[];for(let r of Fa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function kn(e,t){t.append(...Array.from(e.childNodes))}function fr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Wa(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,wn(p,i)),s.replaceWith(a.get(p)))}return a.size===0?S:C(()=>{let s=new g,p=s.pipe(Z(),ie(!0)),c=[];for(let[l,f]of a)c.push([R(".md-typeset",f),R(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?kn(f,u):kn(u,f)}),O(...[...a].map(([,l])=>Cn(l,t,{target$:r}))).pipe(_(()=>s.complete()),pe())})}function Hn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Hn(t)}}function $n(e,t){return C(()=>{let r=Hn(e);return typeof r!="undefined"?fr(r,e,t):S})}var Pn=Lt(Br());var Ua=0;function Rn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Rn(t)}}function Da(e){return ge(e).pipe(m(({width:t})=>({scrollable:St(e).width>t})),ee("scrollable"))}function In(e,t){let{matches:r}=matchMedia("(hover)"),o=C(()=>{let n=new g,i=n.pipe(jr(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Pn.default.isSupported()&&(e.closest(".copy")||B("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${Ua++}`;let l=Tn(c.id);c.insertBefore(l,e),B("content.tooltips")&&a.push(mt(l,{viewport$}))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=Rn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||B("content.code.annotate"))){let l=fr(c,e,t);a.push(ge(s).pipe(U(i),m(({width:f,height:u})=>f&&u),K(),v(f=>f?l:S)))}}return P(":scope > span[id]",e).length&&e.classList.add("md-code__content"),Da(e).pipe(w(c=>n.next(c)),_(()=>n.complete()),m(c=>$({ref:e},c)),Re(...a))});return B("content.lazy")?tt(e).pipe(b(n=>n),Te(1),v(()=>o)):o}function Va(e,{target$:t,print$:r}){let o=!0;return O(t.pipe(m(n=>n.closest("details:not([open])")),b(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(b(n=>n||!o),w(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function jn(e,t){return C(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Va(e,t).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}var Fn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var Gr,za=0;function qa(){return typeof mermaid=="undefined"||mermaid instanceof Element?Tt("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):I(void 0)}function Wn(e){return e.classList.remove("mermaid"),Gr||(Gr=qa().pipe(w(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Fn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),G(1))),Gr.subscribe(()=>so(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${za++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),Gr.pipe(m(()=>({ref:e})))}var Un=x("table");function Dn(e){return e.replaceWith(Un),Un.replaceWith(_n(e)),I({ref:e})}function Qa(e){let t=e.find(r=>r.checked)||e[0];return O(...e.map(r=>h(r,"change").pipe(m(()=>R(`label[for="${r.id}"]`))))).pipe(Q(R(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Vn(e,{viewport$:t,target$:r}){let o=R(".tabbed-labels",e),n=P(":scope > input",e),i=Kr("prev");e.append(i);let a=Kr("next");return e.append(a),C(()=>{let s=new g,p=s.pipe(Z(),ie(!0));z([s,ge(e),tt(e)]).pipe(U(p),Le(1,me)).subscribe({next([{active:c},l]){let f=Ve(c),{width:u}=ce(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=pr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([Ne(o),ge(o)]).pipe(U(p)).subscribe(([c,l])=>{let f=St(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),O(h(i,"click").pipe(m(()=>-1)),h(a,"click").pipe(m(()=>1))).pipe(U(p)).subscribe(c=>{let{width:l}=ce(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(U(p),b(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=R(`label[for="${c.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(U(p),b(f=>!(f.metaKey||f.ctrlKey)),w(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return B("content.tabs.link")&&s.pipe(Ce(1),re(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let y of P("[data-tabs]"))for(let M of P(":scope > input",y)){let X=R(`label[for="${M.id}"]`);if(X!==c&&X.innerText.trim()===f){X.setAttribute("data-md-switching",""),M.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),s.pipe(U(p)).subscribe(()=>{for(let c of P("audio, video",e))c.pause()}),Qa(n).pipe(w(c=>s.next(c)),_(()=>s.complete()),m(c=>$({ref:e},c)))}).pipe(Ke(se))}function Nn(e,{viewport$:t,target$:r,print$:o}){return O(...P(".annotate:not(.highlight)",e).map(n=>$n(n,{target$:r,print$:o})),...P("pre:not(.mermaid) > code",e).map(n=>In(n,{target$:r,print$:o})),...P("pre.mermaid",e).map(n=>Wn(n)),...P("table:not([class])",e).map(n=>Dn(n)),...P("details",e).map(n=>jn(n,{target$:r,print$:o})),...P("[data-tabs]",e).map(n=>Vn(n,{viewport$:t,target$:r})),...P("[title]",e).filter(()=>B("content.tooltips")).map(n=>mt(n,{viewport$:t})))}function Ka(e,{alert$:t}){return t.pipe(v(r=>O(I(!0),I(!1).pipe(Ge(2e3))).pipe(m(o=>({message:r,active:o})))))}function zn(e,t){let r=R(".md-typeset",e);return C(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ka(e,t).pipe(w(n=>o.next(n)),_(()=>o.complete()),m(n=>$({ref:e},n)))})}var Ya=0;function Ba(e,t){document.body.append(e);let{width:r}=ce(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=cr(t),n=typeof o!="undefined"?Ne(o):I({x:0,y:0}),i=O(et(t),$t(t)).pipe(K());return z([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=Ve(t),l=ce(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function qn(e){let t=e.title;if(!t.length)return S;let r=`__tooltip_${Ya++}`,o=Rt(r,"inline"),n=R(".md-typeset",o);return n.innerHTML=t,C(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),O(i.pipe(b(({active:a})=>a)),i.pipe(_e(250),b(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Le(16,me)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(pt(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ba(o,e).pipe(w(a=>i.next(a)),_(()=>i.complete()),m(a=>$({ref:e},a)))}).pipe(Ke(se))}function Ga({viewport$:e}){if(!B("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Be(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),K()),o=ze("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),K(),v(n=>n?r:I(!1)),Q(!1))}function Qn(e,t){return C(()=>z([ge(e),Ga(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),K((r,o)=>r.height===o.height&&r.hidden===o.hidden),G(1))}function Kn(e,{header$:t,main$:r}){return C(()=>{let o=new g,n=o.pipe(Z(),ie(!0));o.pipe(ee("active"),He(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=ue(P("[title]",e)).pipe(b(()=>B("content.tooltips")),ne(a=>qn(a)));return r.subscribe(o),t.pipe(U(n),m(a=>$({ref:e},a)),Re(i.pipe(U(n))))})}function Ja(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ce(e);return{active:o>=n}}),ee("active"))}function Yn(e,t){return C(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?S:Ja(o,t).pipe(w(n=>r.next(n)),_(()=>r.complete()),m(n=>$({ref:e},n)))})}function Bn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),K()),n=o.pipe(v(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ee("bottom"))));return z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Xa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return I(...e).pipe(ne(o=>h(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),G(1))}function Gn(e){let t=P("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Pt("(prefers-color-scheme: light)");return C(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;sa.key==="Enter"),re(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Se("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(ve(se)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Xa(t).pipe(U(n.pipe(Ce(1))),ct(),w(a=>i.next(a)),_(()=>i.complete()),m(a=>$({ref:e},a)))})}function Jn(e,{progress$:t}){return C(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(w(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Jr=Lt(Br());function Za(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Xn({alert$:e}){Jr.default.isSupported()&&new j(t=>{new Jr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Za(R(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(w(t=>{t.trigger.focus()}),m(()=>Ee("clipboard.copied"))).subscribe(e)}function Zn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function es(e,t){let r=new Map;for(let o of P("url",e)){let n=R("loc",o),i=[Zn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of P("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Zn(new URL(s),t))}}return r}function ur(e){return fn(new URL("sitemap.xml",e)).pipe(m(t=>es(t,new URL(e))),de(()=>I(new Map)))}function ts(e,t){if(!(e.target instanceof Element))return S;let r=e.target.closest("a");if(r===null)return S;if(r.target||e.metaKey||e.ctrlKey)return S;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),I(new URL(r.href))):S}function ei(e){let t=new Map;for(let r of P(":scope > *",e.head))t.set(r.outerHTML,r);return t}function ti(e){for(let t of P("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return I(e)}function rs(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...B("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=ei(document);for(let[o,n]of ei(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Se("container");return Ue(P("script",r)).pipe(v(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),S}),Z(),ie(document))}function ri({location$:e,viewport$:t,progress$:r}){let o=xe();if(location.protocol==="file:")return S;let n=ur(o.base);I(document).subscribe(ti);let i=h(document.body,"click").pipe(He(n),v(([p,c])=>ts(p,c)),pe()),a=h(window,"popstate").pipe(m(ye),pe());i.pipe(re(t)).subscribe(([p,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",p)}),O(i,a).subscribe(e);let s=e.pipe(ee("pathname"),v(p=>mn(p,{progress$:r}).pipe(de(()=>(lt(p,!0),S)))),v(ti),v(rs),pe());return O(s.pipe(re(e,(p,c)=>c)),s.pipe(v(()=>e),ee("pathname"),v(()=>e),ee("hash")),e.pipe(K((p,c)=>p.pathname===c.pathname&&p.hash===c.hash),v(()=>i),w(()=>history.back()))).subscribe(p=>{var c,l;history.state!==null||!p.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",cn(p.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(ee("offset"),_e(100)).subscribe(({offset:p})=>{history.replaceState(p,"")}),s}var oi=Lt(qr());function ni(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,oi.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function jt(e){return e.type===1}function dr(e){return e.type===3}function ii(e,t){let r=gn(e);return O(I(location.protocol!=="file:"),ze("search")).pipe(Ae(o=>o),v(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:B("search.suggest")}}})),r}function ai({document$:e}){let t=xe(),r=je(new URL("../versions.json",t.base)).pipe(de(()=>S)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),v(n=>h(document.body,"click").pipe(b(i=>!i.metaKey&&!i.ctrlKey),re(o),v(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?S:(i.preventDefault(),I(p))}}return S}),v(i=>ur(new URL(i)).pipe(m(a=>{let p=ye().href.replace(t.base,i);return a.has(p.split("#")[0])?new URL(p):new URL(i)})))))).subscribe(n=>lt(n,!0)),z([r,o]).subscribe(([n,i])=>{R(".md-header__topic").appendChild(An(n,i))}),e.pipe(v(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases.concat(n.version))if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ae("outdated"))s.hidden=!1})}function is(e,{worker$:t}){let{searchParams:r}=ye();r.has("q")&&(Je("search",!0),e.value=r.get("q"),e.focus(),ze("search").pipe(Ae(i=>!i)).subscribe(()=>{let i=ye();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=et(e),n=O(t.pipe(Ae(jt)),h(e,"keyup"),o).pipe(m(()=>e.value),K());return z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),G(1))}function si(e,{worker$:t}){let r=new g,o=r.pipe(Z(),ie(!0));z([t.pipe(Ae(jt)),r],(i,a)=>a).pipe(ee("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ee("focus")).subscribe(({focus:i})=>{i&&Je("search",i)}),h(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=R("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),is(e,{worker$:t}).pipe(w(i=>r.next(i)),_(()=>r.complete()),m(i=>$({ref:e},i)),G(1))}function ci(e,{worker$:t,query$:r}){let o=new g,n=rn(e.parentElement).pipe(b(Boolean)),i=e.parentElement,a=R(":scope > :first-child",e),s=R(":scope > :last-child",e);ze("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(re(r),Ur(t.pipe(Ae(jt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Ee("search.result.none"):Ee("search.result.placeholder");break;case 1:a.textContent=Ee("search.result.one");break;default:let u=sr(l.length);a.textContent=Ee("search.result.other",u)}});let p=o.pipe(w(()=>s.innerHTML=""),v(({items:l})=>O(I(...l.slice(0,10)),I(...l.slice(10)).pipe(Be(4),Vr(n),v(([f])=>f)))),m(Mn),pe());return p.subscribe(l=>s.appendChild(l)),p.pipe(ne(l=>{let f=fe("details",l);return typeof f=="undefined"?S:h(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(b(dr),m(({data:l})=>l)).pipe(w(l=>o.next(l)),_(()=>o.complete()),m(l=>$({ref:e},l)))}function as(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ye();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function pi(e,t){let r=new g,o=r.pipe(Z(),ie(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),as(e,t).pipe(w(n=>r.next(n)),_(()=>r.complete()),m(n=>$({ref:e},n)))}function li(e,{worker$:t,keyboard$:r}){let o=new g,n=Se("search-query"),i=O(h(n,"keydown"),h(n,"focus")).pipe(ve(se),m(()=>n.value),K());return o.pipe(He(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(b(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(b(dr),m(({data:s})=>s)).pipe(w(s=>o.next(s)),_(()=>o.complete()),m(()=>({ref:e})))}function mi(e,{index$:t,keyboard$:r}){let o=xe();try{let n=ii(o.search,t),i=Se("search-query",e),a=Se("search-result",e);h(e,"click").pipe(b(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Je("search",!1)),r.pipe(b(({mode:p})=>p==="search")).subscribe(p=>{let c=Ie();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of P(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}p.claim()}break;case"Escape":case"Tab":Je("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...P(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Ie()&&i.focus()}}),r.pipe(b(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=si(i,{worker$:n});return O(s,ci(a,{worker$:n,query$:s})).pipe(Re(...ae("search-share",e).map(p=>pi(p,{query$:s})),...ae("search-suggest",e).map(p=>li(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ye}}function fi(e,{index$:t,location$:r}){return z([t,r.pipe(Q(ye()),b(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>ni(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=x("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function ss(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function Xr(e,o){var n=o,{header$:t}=n,r=ao(n,["header$"]);let i=R(".md-sidebar__scrollwrap",e),{y:a}=Ve(i);return C(()=>{let s=new g,p=s.pipe(Z(),ie(!0)),c=s.pipe(Le(0,me));return c.pipe(re(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(Ae()).subscribe(()=>{for(let l of P(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ce(f);f.scrollTo({top:u-d/2})}}}),ue(P("label[tabindex]",e)).pipe(ne(l=>h(l,"click").pipe(ve(se),m(()=>l),U(p)))).subscribe(l=>{let f=R(`[id="${l.htmlFor}"]`);R(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),ss(e,r).pipe(w(l=>s.next(l)),_(()=>s.complete()),m(l=>$({ref:e},l)))})}function ui(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return st(je(`${r}/releases/latest`).pipe(de(()=>S),m(o=>({version:o.tag_name})),De({})),je(r).pipe(de(()=>S),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),De({}))).pipe(m(([o,n])=>$($({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return je(r).pipe(m(o=>({repositories:o.public_repos})),De({}))}}function di(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return st(je(`${r}/releases/permalink/latest`).pipe(de(()=>S),m(({tag_name:o})=>({version:o})),De({})),je(r).pipe(de(()=>S),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),De({}))).pipe(m(([o,n])=>$($({},o),n)))}function hi(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return ui(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return di(r,o)}return S}var cs;function ps(e){return cs||(cs=C(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(ae("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return S}return hi(e.href).pipe(w(o=>__md_set("__source",o,sessionStorage)))}).pipe(de(()=>S),b(t=>Object.keys(t).length>0),m(t=>({facts:t})),G(1)))}function bi(e){let t=R(":scope > :last-child",e);return C(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(Ln(o)),t.classList.add("md-source__repository--active")}),ps(e).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}function ls(e,{viewport$:t,header$:r}){return ge(document.body).pipe(v(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ee("hidden"))}function vi(e,t){return C(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(B("navigation.tabs.sticky")?I({hidden:!1}):ls(e,t)).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}function ms(e,{viewport$:t,header$:r}){let o=new Map,n=P(".md-nav__link",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(ee("height"),m(({height:s})=>{let p=Se("main"),c=R(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),pe());return ge(document.body).pipe(ee("height"),v(s=>C(()=>{let p=[];return I([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),He(i),v(([p,c])=>t.pipe(Fr(([l,f],{offset:{y:u},size:d})=>{let y=u+d.height>=Math.floor(s.height);for(;f.length;){let[,M]=f[0];if(M-c=u&&!y)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),K((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),Q({prev:[],next:[]}),Be(2,1),m(([s,p])=>s.prev.length{let i=new g,a=i.pipe(Z(),ie(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),B("toc.follow")){let s=O(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(b(({prev:p})=>p.length>0),He(o.pipe(ve(se))),re(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=cr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ce(f);f.scrollTo({top:u-d/2,behavior:c})}}})}return B("navigation.tracking")&&t.pipe(U(a),ee("offset"),_e(250),Ce(1),U(n.pipe(Ce(1))),ct({delay:250}),re(i)).subscribe(([,{prev:s}])=>{let p=ye(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),ms(e,{viewport$:t,header$:r}).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))})}function fs(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Be(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return z([i,n]).pipe(m(([a,s])=>!(a&&s)),K(),U(o.pipe(Ce(1))),ie(!0),ct({delay:250}),m(a=>({hidden:a})))}function yi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(Z(),ie(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),ee("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),h(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),fs(e,{viewport$:t,main$:o,target$:n}).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))}function xi({document$:e,viewport$:t}){e.pipe(v(()=>P(".md-ellipsis")),ne(r=>tt(r).pipe(U(e.pipe(Ce(1))),b(o=>o),m(()=>r),Te(1))),b(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,B("content.tooltips")?mt(n,{viewport$:t}).pipe(U(e.pipe(Ce(1))),_(()=>n.removeAttribute("title"))):S})).subscribe(),B("content.tooltips")&&e.pipe(v(()=>P(".md-status")),ne(r=>mt(r,{viewport$:t}))).subscribe()}function Ei({document$:e,tablet$:t}){e.pipe(v(()=>P(".md-toggle--indeterminate")),w(r=>{r.indeterminate=!0,r.checked=!1}),ne(r=>h(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),re(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function us(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function wi({document$:e}){e.pipe(v(()=>P("[data-md-scrollfix]")),w(t=>t.removeAttribute("data-md-scrollfix")),b(us),ne(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ti({viewport$:e,tablet$:t}){z([ze("search"),t]).pipe(m(([r,o])=>r&&!o),v(r=>I(r).pipe(Ge(r?400:100))),re(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ds(){return location.protocol==="file:"?Tt(`${new URL("search/search_index.js",Zr.base)}`).pipe(m(()=>__index),G(1)):je(new URL("search/search_index.json",Zr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ot=Bo(),Wt=an(),Mt=pn(Wt),eo=nn(),Oe=vn(),hr=Pt("(min-width: 960px)"),Oi=Pt("(min-width: 1220px)"),Mi=ln(),Zr=xe(),Li=document.forms.namedItem("search")?ds():Ye,to=new g;Xn({alert$:to});var ro=new g;B("navigation.instant")&&ri({location$:Wt,viewport$:Oe,progress$:ro}).subscribe(ot);var Si;((Si=Zr.version)==null?void 0:Si.provider)==="mike"&&ai({document$:ot});O(Wt,Mt).pipe(Ge(125)).subscribe(()=>{Je("drawer",!1),Je("search",!1)});eo.pipe(b(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&<(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&<(r);break;case"Enter":let o=Ie();o instanceof HTMLLabelElement&&o.click()}});xi({viewport$:Oe,document$:ot});Ei({document$:ot,tablet$:hr});wi({document$:ot});Ti({viewport$:Oe,tablet$:hr});var rt=Qn(Se("header"),{viewport$:Oe}),Ft=ot.pipe(m(()=>Se("main")),v(e=>Bn(e,{viewport$:Oe,header$:rt})),G(1)),hs=O(...ae("consent").map(e=>xn(e,{target$:Mt})),...ae("dialog").map(e=>zn(e,{alert$:to})),...ae("header").map(e=>Kn(e,{viewport$:Oe,header$:rt,main$:Ft})),...ae("palette").map(e=>Gn(e)),...ae("progress").map(e=>Jn(e,{progress$:ro})),...ae("search").map(e=>mi(e,{index$:Li,keyboard$:eo})),...ae("source").map(e=>bi(e))),bs=C(()=>O(...ae("announce").map(e=>yn(e)),...ae("content").map(e=>Nn(e,{viewport$:Oe,target$:Mt,print$:Mi})),...ae("content").map(e=>B("search.highlight")?fi(e,{index$:Li,location$:Wt}):S),...ae("header-title").map(e=>Yn(e,{viewport$:Oe,header$:rt})),...ae("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Nr(Oi,()=>Xr(e,{viewport$:Oe,header$:rt,main$:Ft})):Nr(hr,()=>Xr(e,{viewport$:Oe,header$:rt,main$:Ft}))),...ae("tabs").map(e=>vi(e,{viewport$:Oe,header$:rt})),...ae("toc").map(e=>gi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Mt})),...ae("top").map(e=>yi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Mt})))),_i=ot.pipe(v(()=>bs),Re(hs),G(1));_i.subscribe();window.document$=ot;window.location$=Wt;window.target$=Mt;window.keyboard$=eo;window.viewport$=Oe;window.tablet$=hr;window.screen$=Oi;window.print$=Mi;window.alert$=to;window.progress$=ro;window.component$=_i;})(); +//# sourceMappingURL=bundle.56dfad97.min.js.map + diff --git a/assets/javascripts/bundle.56dfad97.min.js.map b/assets/javascripts/bundle.56dfad97.min.js.map new file mode 100644 index 00000000..eb83bdb3 --- /dev/null +++ b/assets/javascripts/bundle.56dfad97.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/escape-html/index.js", "node_modules/clipboard/dist/clipboard.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/tslib/tslib.es6.mjs", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an + +

Histórico de Revisão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
17/04/241.0Criação do documentoMarco Tulio, Joyce DionizioLucas Antunes
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade2/apresentacao2/index.html b/sections/entregas/unidade2/apresentacao2/index.html new file mode 100644 index 00000000..c4d09e19 --- /dev/null +++ b/sections/entregas/unidade2/apresentacao2/index.html @@ -0,0 +1,1670 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 2 | Backlog - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Missão 2 | Backlog

+ +

1. Introdução

+

RISO é um software projetado para medir a satisfação dos clientes em uma loja específica, analisando suas expressões faciais por meio de tecnologias de visão computacional. Este documento de backlog visa apresentar:

+
    +
  • Histórias de Usuário (US's)
  • +
  • Requisitos Não Funcionais
  • +
  • Backlog
  • +
+

2. User Storys (USs)

+

User Story (ou história do usuário) é uma sentença curta e simples sobre uma funcionalidade (escrita sob a perspectiva do usuário que a deseja), utilizada para informar e inspirar decisões de design.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TítuloHistória de Usuário
US01Cadastrar e Logar na ContaEu como usuário, devo ser capaz de me cadastrar e logar na plataforma, para que eu possa utilizar das funções do software e ter a segurança de meus dados.
US02Cadastrar Empresa-UnidadeEu como usuário, devo ser capaz de registrar uma nova Unidade/Empresa, para que os dados obtidos pelo sistema RISO seja acessada apenas pelos associados à esta Unidade/Empresa.
US03Adicionar ColaboradoresEu como Administrador da Unidade/Empresa, devo ser capaz de adicionar colaboradores a partir de um código aleatório gerado no ato da criação da Unidade/Empresa, para que mais pessoas possam acompanhar os dados obtido pelo sistema RISO.
US04Editar ColaboradoresEu como Usuário administrador da Unidade/Empresa, devo ser capaz de atribuir os dados profissionais internos de qualquer colaborador associado à minha Unidade/Empresa, para que eu organize melhor as atribuições da equipe dentro da plataforma.
US05Gerenciar PrivilégiosEu como usuário administrador, devo ser capaz de adicionar e remover usuários privilegiados de minha Unidade/Empresa, isto é, de gerenciar sub-administradores, para que outros usuários possam me dar assistência no gerenciamento da Unidade/Empresa além de mim.
US06Reconhecer SorrisosO sistema deve ser capaz de capturar sorrisos de uma pessoa a partir da visão computacional fornecida por uma câmera ou webcam, para que o reconhecimento de sorrisos aconteça.
US07Contabilizar SorrisosO sistema, deve ser capaz de contabilizar a quantidade de sorrisos totais da clientela no dia, e por pessoa no dia, para que os dados possam ficar organizados posteriormente.
US08Visualizar filtro de gráfico de sorrisos por dia, semana e mêsEu como usuário comum e administrador, devo ser capaz de visualizar um gráfico da quantidade total de sorrisos por dia, semana ou mês, para que eu tenha visão clara e facilidade dos dados.
US09Visualizar gráfico de média de sorrisos por pessoa por dia, semana e mêsEu como usuário e usuário administrador, devo ser capaz de visualizar a quantidade média de sorrisos por pessoa filtrada por dia, semana ou mês, para que eu possa consultar os dados facilmente de forma clara e de forma mais clara.
US10Visualizar dados de taxas gerais de risosEu como usuário e usuário administrador, devo ser capaz de visualizar uma taxa em porcentagem que exibe a quantidade de pessoas capturadas para o levantamentos dos dados no dia e quantas dessas riram, para que eu obtenha dados aprofundados da taxa de sorrisos.
US11Integrar em uma câmera única no CaixaO Sistema, deve ser capaz de capturar e realizar o reconhecimento de sorrisos com uma câmera especializada do cliente, para que o sistema RISO seja devidamente aplicado ao contexto do cliente.
+

2. Requisitos Não Funcionais

+

Requisitos não funcionais são critérios que especificam a operação de um sistema, diferentemente dos requisitos funcionais, que descrevem o comportamento e as funcionalidades do sistema. Eles incluem aspectos como desempenho, segurança, usabilidade, confiabilidade, e conformidade com padrões. Esses requisitos são cruciais para garantir que o sistema não apenas funcione conforme esperado, mas também atenda a determinadas qualidades e restrições que são importantes para os usuários e outras partes interessadas.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoriaDescrição
RQNF01DesignO sistema deverá garantir que o design adotado promova uma facilidade na curva de aprendizagem de uso da plataforma.
RQNF02PortabilidadeO sistema deverá ser um Web.
RQNF03InterfaceO sistema deverá ser utilizável em qualquer dispositivo com acesso à internet, independente do tamanho do visor. Isto é, ser responsivo.
RQNF04SeguraçaO sistema deverá ter páginas protegidas com autenticação do usuário.
RQNF05SegurançaO sistema deverá criptografar dados sensíveis dos usuários.
RQNF06DesenpenhoO sistema deverá garantir que as requisições ao banco de dados não durem mais que 1 segundo.
+

4. Backlog

+

O backlog é uma lista prioritária de tarefas, funcionalidades, e requisitos que devem ser implementados em um projeto de desenvolvimento de software. Ele é essencialmente um repositório dinâmico e evolutivo que reflete tudo o que é necessário para melhorar o produto. No contexto do desenvolvimento ágil, o backlog é frequentemente revisitado e reorganizado para assegurar que o trabalho mais valioso seja realizado primeiro. Esse processo contínuo de refinamento ajuda a garantir que a equipe esteja sempre alinhada com as prioridades e objetivos do projeto.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ÉpicoUser StoryObjetivo
[EP01]: Reconhecimento de SorrisosUS11Integrar em uma câmera Única na Caixa
[EP01]: Reconhecimento de SorrisosUS07Contabilizar Sorrisos
[EP01]: Reconhecimento de SorrisosUS06Reconhecer Sorrisos
[EP02]: Visualização de DadosUS09Visualizar gráfico de média de sorrisos por pessoa por dia, semana e mês
[EP02]: Visualização de DadosUS10Visualizar dados de taxas gerais de risos
[EP02]: Visualização de DadosUS08Visualizar filtro de gráfico de sorrisos por dia, semana e mês
[EP03]: Gerenciamento de Unidade/EmpresaUS05Gerenciar Privilégios
[EP03]: Gerenciamento de Unidade/EmpresaUS04Adicionar Colaboradores
[EP03]: Gerenciamento de Unidade/EmpresaUS03Adicionar Colaboradores
[EP04]: Gerenciamento de ContaUS01Cadastrar e Logar na Conta
[EP04]: Gerenciamento de ContaUS02Cadastrar Empresa-Unidade
+

4. Referências Bibliográficas:

+
+

Cursospm3. Glossário: User Story. 2024. Disponível em: https://www.cursospm3.com.br/glossario/user-story/.

+

PRESSMAN, Roger S. Engenharia de Software. 8. ed. Porto Alegre: AMGH, 2016.

+

SCHWABER, Ken; SUTHERLAND, Jeff. The Scrum Guide: The Definitive Guide to Scrum: The Rules of the Game. 2020. Disponível em: https://www.scrumguides.org/scrum-guide.html.

+
+

5. Histórico de Revisão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoMarco Tulio, Joao PedroDaniel Rodrigues
01/08/242.0Adição do Requisito Não FuncionalDaniel RodriguesJoao Pedro
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade2/video/index.html b/sections/entregas/unidade2/video/index.html new file mode 100644 index 00000000..3264f002 --- /dev/null +++ b/sections/entregas/unidade2/video/index.html @@ -0,0 +1,1388 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 2 | Video de Apresentação - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Vídeo da Apresentação do grupo

+ + +

Histórico de Revisão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoDaniel Rodrigues, Lucas AntunesMarco Tulio
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-PBB-CalorieExplorer/index.html b/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-PBB-CalorieExplorer/index.html new file mode 100644 index 00000000..854ba57b --- /dev/null +++ b/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-PBB-CalorieExplorer/index.html @@ -0,0 +1,1500 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 4 | PBB - Verificação e Validação à CalorieExplorer - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Verificação e Validação - PBB do Projeto Calorie Explorer

+

1. Verificação

+

A verificação do PBB (Product Backlog Building) para o projeto Calorie Explorer foi conduzida utilizando um checklist para avaliar se todos os elementos fundamentais do Canvas PBB foram atendidos. Entre os pontos verificados, constatou-se que o Canvas PBB está devidamente identificado com o produto, e os problemas e expectativas do cliente foram corretamente listados. Também foram criadas personas, e as ações associadas a essas personas foram mapeadas, incluindo o que fazem atualmente e o que desejam fazer com o sistema. As funcionalidades foram definidas com base nas ações das personas, identificando os problemas que cada funcionalidade resolve e os benefícios que trazem.

+

No entanto, durante a verificação, foram observadas algumas inconsistências: o PBI "Fazer atualizações e melhorias" não segue corretamente o modelo ARO, apresentando ausência do objeto, e alguns PBIs foram organizados sem seguir a prioridade estabelecida. Além disso, as histórias de usuário, que deveriam ser derivadas diretamente dos PBIs, não seguiram o modelo de escrita proposto, o que gerou inconsistências na forma como as histórias foram elaboradas em relação aos PBIs originais.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaCheckComentários
O Canvas PBB possui um CanvasNÃONão há na documentação da equipe o acesso ao Canvas do PBB.
O Canvas PBB possui a identificação do ProdutoSIM--
Foram listados os problemas atuais do clienteSIM--
Foram listado as expectativas do cliente com o produtoSIM--
Foi realizada a criação de personasSIM--
Foram listadas as ações das personas (O que elas fazem hoje e o que elas desejam fazer com o sistema)SIM--
Foram criadas as funcionalidades a partir das ações das personasSIM--
Foram listadas os problemas em as funcionalidades que elas resolvemSIM--
Foram listadas os benefícios que as funcionalidades trazem às personasSIM--
Foram criados os PBIs das funcionalidades seguindo o modelo ARO.NÃOO PBI "Fazer atualizações e melhorias" possui a ausência do Objeto no modelo ARO. O restante está seguindo o padrão.
Os PBIs foram priorizadosSIM--
Foram criadas as histórias de usuário usando o PBI, personas e benefíciosNÃOA escrita dos PBIs nas US's em comparação às PBIs isoladamente foram alteradas.
As histórias de usuários possuem critérios de aceitaçãoSIM--
Os PBIs estão organizados verticalmente pelo valor de prioridadeNÃOAs US's foram montadas e receberam o seus códicos sem considerar a ordem de prioridade estabelecido nos PBIs.
+

2. Validação

+

A validação do PBB envolveu uma análise detalhada da qualidade e coerência de cada item desenvolvido, comparando-os com o contexto do estudo de caso HealthNet. Os problemas e expectativas identificados foram considerados apropriados e relevantes, assim como as personas e suas atividades. As funcionalidades criadas foram bem associadas às personas e apresentaram um nível adequado de granularidade. No entanto, foi identificado que, em alguns casos, os benefícios descritos para as funcionalidades não eram suficientemente específicos, abrangendo vantagens que poderiam se aplicar a múltiplas funcionalidades, o que comprometeu a clareza.

+

Adicionalmente, observou-se que as User Stories não estavam alinhadas ao modelo padrão de escrita, que envolve a estrutura "Eu, como [persona], posso [ação], para [valor de negócio]". Além disso, os critérios de aceitação, embora relevantes, foram redigidos de maneira inadequada, apresentando a visão das personas como executoras dos critérios, o que dificulta a compreensão das condições necessárias para o funcionamento da User Story. A reformulação dos critérios para um formato mais imparcial e padronizado é necessária para melhorar a qualidade das validações.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaCheckComentários
O PBB está coerente com o estudo de caso HealthNetSIM--
Os problemas identificados são coerentes com o contextoSIM--
As expectativas são coerentes com o contextoSIM--
As personas identificadas são coerentes com o contextoSIM--
As atividades de cada persona são coerentes com a sua declaração e o contextoSIM--
As funcionalidades são coerentes com a persona com a qual estão associadasSIM--
As funcionalidades possuem grau de granularidade altoSIM--
Os problemas de cada funcionalidade são coerentes com a funcionalidade com o qual estão associadosSIM--
Os benefícios de cada funcionalidade são coerentes com a funcionalidade com o qual estão associadosNÃOEm alguns benefícios, o texto não é focado na funcionalidade em sí, mas relata um benefício amplo e que outras funcionalidades poderiam trazer também.
Os PBIs são coerentes com as funcionalidades com a qual estão associadosSIM--
Os PBIs foram escritos com o mesmo modelo (Estão padronizados)SIM--
As USs estão estruturadas no formato: "Eu, como [persona], posso [ação], para [valor de negócio]"NÃONenhuma das User Story seguem o modelo de escrita.
Os critérios de aceitação estão coerentes com a US a qual estão associadosSIM--
Os critérios de aceitação informam apenas as condições para a US funcionarNÃOOs critérios de aceitação foram escritos como se as personas realizassem os critérios. Deverá ser feito pensado em qualquer usuário.
+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
04/09/241.0Criação do documentoDaniel RodriguesJésus Gabriel
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-USM-CalorieExplorer/index.html b/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-USM-CalorieExplorer/index.html new file mode 100644 index 00000000..70837ed9 --- /dev/null +++ b/sections/entregas/unidade3/VeriVal_Fornecidas/VeriVal-USM-CalorieExplorer/index.html @@ -0,0 +1,1503 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 4 | USM - Verificação e Validação à CalorieExplorer - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Verificação e Validação - USM do Projeto Calorie Explorer

+

1. Verificação

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaCheckComentários
O User Story Map está necessário e justificado para o projeto?
O USM está descrito de forma apropriada para o contexto do projeto?
As histórias de usuário estão descritas de forma não ambígua?
O USM cobre todos os requisitos necessários para o produto?
Cada história de usuário é singular e não se sobrepõe a outra?
As funcionalidades mapeadas são viáveis dentro das restrições do projeto?
As histórias de usuário podem ser verificadas e testadas?
O USM está conforme com as regras e padrões de documentação?
O USM está correto com base nas especificações dadas pelo cliente?
Cada item do USM tem uma referência clara à regra específica ou requisito?
+

2. Validação

+ + + + + + + + + + + + + + + +
PerguntaCheckComentários
+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
05/09/241.0Criação do documentoDaniel RodriguesJésus Gabriel
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade3/pbb/index.html b/sections/entregas/unidade3/pbb/index.html new file mode 100644 index 00000000..f6244b82 --- /dev/null +++ b/sections/entregas/unidade3/pbb/index.html @@ -0,0 +1,6017 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 3 | PPB - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Missão 3 - PBB

+

1. Product Backlog Building

+

Product Backlog Building (PBB) é um processo utilizado em metodologias de desenvolvimento de software ágeis, como o Scrum, para criar e manter uma lista de itens de trabalho (ou “backlog”) para um projeto de software. O PBB é realizado pelo Product Owner, que é responsável por definir e priorizar os itens do backlog, com base nas necessidades do negócio e dos usuários. Os itens do backlog incluem histórias do usuário, tarefas técnicas e bugs.

+

O PBB é um processo contínuo que começa antes do início do projeto e continua durante todo o ciclo de vida do projeto. Ele é usado para garantir que o projeto esteja sempre alinhado com as necessidades do negócio e dos usuários, e para garantir que o trabalho do time de desenvolvimento esteja sempre focado nas coisas mais importantes (Medium, 2022).

+

2. HealthNet

+

A HealthNet atua no setor de saúde e enfrenta diversos desafios em sua operação, especialmente relacionados à eficiência dos processos internos, à comunicação entre diferentes departamentos, e à satisfação dos pacientes. Esses problemas indicam uma necessidade urgente de revisão e otimização de suas práticas, bem como a implementação de soluções tecnológicas que possam integrar e melhorar a gestão das suas atividades.

+

Entre as principais necessidades identificadas para a HealthNet estão a melhoria da comunicação interna, a padronização dos processos operacionais, e a criação de um sistema centralizado que permita o acesso rápido e eficiente às informações dos pacientes. Além disso, há uma demanda por ferramentas que auxiliem na análise de dados, visando tanto a melhoria da tomada de decisões quanto a personalização do atendimento aos pacientes.

+

3. Construção do PBB

+

A montagem do Product Backlog utilizando o método PBB foi realizada pela plataforma Miro, software especializado em produção de mapas mentais, organização de notas e tarefas. O Mapa completo pode ser visualizada abaixo:

+

+ +

+

A atividade foi conduzida utilizando um template de PBB disponibilizado pela comunidade do Miro. O template possui áreas específicas para cada etapa da metodologia. Começando pela parte esquerda, são preenchidos os problemas e expectativas identificados. Em seguida, no espaço central mais amplo do template, é realizada a definição das personas.

+

Na próxima etapa, as features são detalhadas com base nas expectativas de cada persona. As features são apresentadas com os problemas ou necessidades relacionados à esquerda e os benefícios proporcionados por cada uma à direita.

+

Logo após, são listados os Itens do Product Backlog, que correspondem às Histórias de Usuários criadas a partir das Features descritas anteriormente. Por fim, a priorização das US’s foi realizada utilizando o método de priorização COORG. Nesse método, a priorização ocorre tanto vertical quanto horizontalmente, com a posição vertical indicando o grau de prioridade (quanto mais alto, maior) e a posição horizontal indicando a sequência lógica de execução.

+

4. Definição de Users Storys e BDDs:

+

A fase de Behavior Driven Development (BDD) no framework Product Backlog Building (PBB) é uma etapa crucial para alinhar o desenvolvimento do software com as expectativas dos usuários e do negócio. O BDD se concentra em descrever o comportamento do sistema por meio de cenários concretos que refletem as necessidades e funcionalidades desejadas. Essas descrições são feitas em uma linguagem comum e acessível, frequentemente utilizando a estrutura “Dado-Quando-Então” para detalhar as condições iniciais, as ações tomadas e os resultados esperados. A fase de BDD no PBB envolve a criação de cenários específicos para cada item do backlog.

+

Para a montagem das US's e BDDs, foi extraído cada PBI obtido pelo método PBB. Os BDDs serão organizados, aqui, por persona.

+

4.1. PERSONA 1 - RECEPCIONISTA

+

User Story:

+
    +
  • Código: US01.

    +Como recepcionista da "HealthNet",
    +Eu quero cadastrar os dados dos pacientes,
    +Para que eu consiga registrar as informações de novos pacientes de forma rápida e sem atrasos, facilitando o atendimento inicial e o acesso a seus históricos médicos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Cadastro de um novo paciente com todos os campos obrigatórios preenchidos corretamente
+

Dado que a recepcionista está na tela de cadastro de pacientes,
+E todos os campos obrigatórios (nome, data de nascimento, endereço, telefone, CPF, e histórico médico básico) estão visíveis,
+Quando ela preenche todos os campos corretamente e clica no botão "Cadastrar",
+Então o sistema deve salvar os dados do paciente,
+E exibir uma mensagem de confirmação "Paciente cadastrado com sucesso",
+E redirecionar para a página de listagem de pacientes.

+
Cenário 2: Tentativa de cadastro com campos obrigatórios não preenchidos
+

Dado que a recepcionista está na tela de cadastro de pacientes,
+Quando ela tenta cadastrar o paciente sem preencher todos os campos obrigatórios (ex.: CPF ou data de nascimento em branco),
+Então o sistema deve impedir o cadastro,
+E exibir uma mensagem de erro indicando quais campos precisam ser preenchidos, como "Por favor, preencha o campo CPF".

+
Cenário 3: Cadastro de paciente com CPF já registrado
+

Dado que um paciente com o mesmo CPF já está cadastrado no sistema,
+E a recepcionista está tentando cadastrar um novo paciente com o mesmo CPF,
+Quando ela clica no botão "Cadastrar",
+Então o sistema deve bloquear o cadastro,
+E exibir uma mensagem de erro "CPF já registrado. Verifique as informações do paciente".

+
Cenário 4: Preenchimento automático de endereço pelo CEP
+

Dado que a recepcionista está na tela de cadastro de pacientes,
+E o campo de CEP está disponível,
+Quando ela insere um CEP válido no campo correspondente,
+Então o sistema deve preencher automaticamente os campos de endereço (rua, bairro, cidade e estado),
+E permitir que a recepcionista revise e edite essas informações, se necessário.

+
Cenário 5: Validação dos dados inseridos no cadastro
+

Dado que a recepcionista está na tela de cadastro de pacientes,
+E inseriu os dados nos campos de forma incorreta, como nome com números ou telefone com formato inválido,
+Quando ela tenta prosseguir com o cadastro,
+Então o sistema deve exibir mensagens específicas de erro junto aos campos incorretos, como "Nome não pode conter números" ou "Formato de telefone inválido".

+
Cenário 6: Cancelamento do cadastro durante o processo
+

Dado que a recepcionista está no meio do processo de cadastro de um paciente,
+Quando ela clica no botão "Cancelar",
+Então o sistema deve exibir uma mensagem de confirmação "Tem certeza que deseja cancelar o cadastro?",
+E se a recepcionista confirmar o cancelamento, o sistema deve descartar todos os dados inseridos,
+E retornar para a tela inicial de cadastro ou listagem de pacientes.

+
+ +

User Story:

+
    +
  • Código: US02

    +Como recepcionista da "HealthNet",
    +Eu quero atualizar os dados dos pacientes,
    +Para que eu consiga corrigir ou adicionar informações nos cadastros de pacientes existentes, garantindo que os dados estejam sempre atualizados e corretos para melhor atendimento. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Atualização bem-sucedida de dados de um paciente
+

Dado que a recepcionista está na tela de edição dos dados de um paciente,
+E todos os campos editáveis estão visíveis e acessíveis,
+Quando ela altera as informações (ex.: endereço ou telefone) e clica no botão "Salvar Alterações",
+Então o sistema deve atualizar os dados do paciente no banco de dados,
+E exibir uma mensagem de confirmação "Dados do paciente atualizados com sucesso",
+E retornar à página de visualização dos dados atualizados do paciente.

+
Cenário 2: Tentativa de atualização com campos obrigatórios deixados em branco
+

Dado que a recepcionista está na tela de atualização dos dados de um paciente,
+Quando ela apaga informações de um campo obrigatório (ex.: CPF ou data de nascimento) e tenta salvar as alterações,
+Então o sistema deve impedir a atualização,
+E exibir uma mensagem de erro "Preencha todos os campos obrigatórios".

+
Cenário 3: Atualização de dados com um CPF que já pertence a outro paciente
+

Dado que a recepcionista está atualizando os dados de um paciente,
+E insere um CPF que já está registrado em outro cadastro no sistema,
+Quando ela tenta salvar as alterações,
+Então o sistema deve bloquear a atualização,
+E exibir uma mensagem de erro "CPF já cadastrado para outro paciente".

+
Cenário 4: Validação de dados durante a atualização
+

Dado que a recepcionista está na tela de edição dos dados de um paciente,
+E ela insere informações incorretas, como um telefone com formato inválido ou nome com caracteres especiais,
+Quando ela clica no botão "Salvar Alterações",
+Então o sistema deve exibir mensagens específicas de erro junto aos campos incorretos, como "Formato de telefone inválido" ou "Nome não pode conter caracteres especiais".

+
Cenário 5: Cancelamento da atualização dos dados
+

Dado que a recepcionista está atualizando os dados de um paciente,
+Quando ela clica no botão "Cancelar" antes de salvar as alterações,
+Então o sistema deve exibir uma mensagem de confirmação "Tem certeza que deseja cancelar as alterações?",
+E se a recepcionista confirmar o cancelamento, o sistema deve descartar todas as mudanças feitas,
+E retornar à tela de visualização dos dados originais do paciente sem alterações.

+
Cenário 6: Atualização de dados com preenchimento automático de endereço pelo CEP
+

Dado que a recepcionista está na tela de atualização dos dados de um paciente,
+E o campo de CEP está disponível para edição,
+Quando ela insere um CEP válido no campo correspondente,
+Então o sistema deve preencher automaticamente os campos de endereço (rua, bairro, cidade e estado),
+E permitir que a recepcionista revise e edite essas informações, se necessário.

+
+ +

4.2. PERSONA 2 - MÉDICO CLÍNICO GERAL

+

User Story:

+
    +
  • Código: US03

    +Como Médico Clínico Geral
    +Eu quero adicionar prescrições médicas dos pacientes
    +Para que os tratamentos recomendados estejam registrados no prontuário e possam ser facilmente acessados por outros profissionais de saúde, garantindo continuidade e segurança no tratamento. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Adicionar uma nova prescrição com sucesso
+

Dado que o médico está autenticado no sistema e visualizando o prontuário do paciente
+E há um botão ou campo para adicionar uma nova prescrição
+Quando o médico insere as informações da prescrição (nome do medicamento, dosagem, frequência, duração do tratamento, etc.)
+E clica no botão "Salvar"
+Então a prescrição é salva no sistema
+E aparece uma mensagem de confirmação "Prescrição adicionada com sucesso"
+E a prescrição fica visível no histórico de prescrições do paciente.

+
Cenário 2: Validar campos obrigatórios ao adicionar uma prescrição
+

Dado que o médico está adicionando uma nova prescrição
+Quando o médico tenta salvar a prescrição sem preencher todos os campos obrigatórios (como nome do medicamento ou dosagem)
+Então o sistema deve exibir uma mensagem de erro "Preencha todos os campos obrigatórios"
+E o sistema não deve salvar a prescrição até que todas as informações necessárias sejam inseridas.

+
Cenário 3: Alerta de interação medicamentosa ao adicionar uma nova prescrição
+

Dado que o médico está adicionando uma nova prescrição para um paciente com outras prescrições já registradas
+E o sistema tem acesso aos dados de interação medicamentosa
+Quando o médico insere uma prescrição que interage de forma adversa com os medicamentos atuais do paciente
+Então o sistema deve exibir um alerta "Cuidado: Interação medicamentosa detectada"
+E o médico deve poder revisar a prescrição antes de confirmar.

+
Cenário 4: Visualizar histórico completo de prescrições ao adicionar uma nova prescrição
+

Dado que o médico está no prontuário do paciente
+Quando o médico clica para adicionar uma nova prescrição
+Então o sistema deve exibir o histórico completo de prescrições anteriores
+E deve mostrar alertas relevantes, como histórico de alergias ou medicamentos suspensos.

+
Cenário 5: Editar uma prescrição antes de confirmar
+

Dado que o médico inseriu informações incorretas ou incompletas na nova prescrição
+Quando o médico clica em "Editar" antes de confirmar a prescrição
+Então o sistema deve permitir a edição dos campos preenchidos
+E o médico pode corrigir as informações antes de salvar definitivamente.

+
+ +

User Story:

+
    +
  • Código: US04

    +Como Médico Clínico Geral
    +Eu quero editar prescrições médicas dos pacientes
    +Para que eu possa corrigir, ajustar dosagens, ou atualizar informações de tratamento conforme o quadro clínico do paciente evolui. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Editar uma prescrição com sucesso
+

Dado que o médico está autenticado no sistema e visualizando o prontuário do paciente
+E há uma prescrição médica existente no prontuário
+Quando o médico seleciona a prescrição que deseja editar
+E modifica os campos necessários (nome do medicamento, dosagem, frequência, etc.)
+E clica no botão "Salvar alterações"
+Então o sistema atualiza a prescrição com as novas informações
+E exibe uma mensagem de confirmação "Prescrição atualizada com sucesso".

+
Cenário 2: Validar campos obrigatórios ao editar uma prescrição
+

Dado que o médico está editando uma prescrição existente
+Quando o médico tenta salvar a prescrição sem preencher todos os campos obrigatórios
+Então o sistema deve exibir uma mensagem de erro "Preencha todos os campos obrigatórios"
+E o sistema não deve salvar as alterações até que todas as informações necessárias sejam inseridas.

+
Cenário 3: Exibir histórico de edições da prescrição
+

Dado que o médico está visualizando uma prescrição editada anteriormente
+Quando o médico seleciona a prescrição para visualizar ou editar
+Então o sistema deve exibir um histórico de edições, incluindo quem realizou a edição, quando, e quais alterações foram feitas
+E deve permitir que o médico veja as versões anteriores para referência.

+
Cenário 4: Alerta de interação medicamentosa após edição
+

Dado que o médico está editando uma prescrição que interage com outra medicação do paciente
+E o sistema possui dados sobre interações medicamentosas
+Quando o médico salva a prescrição com mudanças que podem causar uma interação adversa
+Então o sistema exibe um alerta "Cuidado: Interação medicamentosa detectada"
+E o médico deve poder revisar as alterações antes de confirmar.

+
Cenário 5: Reverter uma edição de prescrição
+

Dado que o médico realizou uma edição incorreta em uma prescrição
+Quando o médico clica na opção "Reverter para versão anterior"
+Então o sistema restaura a prescrição à versão selecionada
+E exibe uma mensagem de confirmação "Prescrição revertida com sucesso".

+
+ +

User Story:

+
    +
  • Código: US05

    +Como Médico Clínico Geral
    +Eu quero visualizar os dados de histórico médico do paciente
    +Para que eu possa ter uma visão completa das condições passadas, tratamentos, alergias e outros dados relevantes que possam impactar o atendimento atual. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Visualizar o histórico médico completo do paciente
+

Dado que o médico está autenticado no sistema e acessa o prontuário de um paciente
+Quando o médico clica na seção "Histórico Médico"
+Então o sistema exibe o histórico completo, incluindo diagnósticos passados, tratamentos realizados, cirurgias, alergias e histórico de medicações.

+
Cenário 2: Filtrar o histórico médico por tipo de informação
+

Dado que o médico está visualizando o histórico médico do paciente
+Quando o médico utiliza os filtros de visualização (ex.: por data, tipo de consulta, medicação)
+Então o sistema exibe apenas as informações relevantes de acordo com o filtro selecionado
+E mantém os demais registros ocultos até que os filtros sejam removidos.

+
Cenário 3: Acessar detalhes de consultas anteriores
+

Dado que o médico está visualizando o histórico médico
+Quando o médico clica em uma consulta específica no histórico
+Então o sistema exibe os detalhes dessa consulta, incluindo anotações médicas, resultados de exames, e tratamentos recomendados na época.

+
Cenário 4: Visualizar histórico de prescrições e medicações
+

Dado que o médico está visualizando o histórico do paciente
+Quando o médico seleciona a aba "Prescrições e Medicações"
+Então o sistema exibe todas as prescrições passadas, com datas, dosagens e motivos para a prescrição
+E alerta sobre possíveis interações com medicações atuais do paciente.

+
+ +

4.3. PERSONA 3 - PACIENTE

+

User Story:

+
    +
  • Código: US06

    +Como Paciente
    +Eu quero acessar os dados das minhas consultas
    +Para que eu possa revisar informações importantes, como diagnósticos, prescrições e próximos agendamentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Acessar histórico de consultas
+

Dado que o paciente está autenticado no sistema
+Quando o paciente acessa a seção de histórico de consultas
+Então o sistema exibe uma lista de todas as consultas anteriores com detalhes como data, médico, diagnóstico e tratamento recomendado.

+
Cenário 2: Visualizar detalhes específicos de uma consulta
+

Dado que o paciente está visualizando seu histórico de consultas
+Quando o paciente seleciona uma consulta específica na lista
+Então o sistema exibe os detalhes completos da consulta selecionada, incluindo observações médicas, resultados de exames e prescrições.

+
Cenário 3: Filtrar consultas por data ou especialidade
+

Dado que o paciente deseja encontrar consultas específicas
+Quando o paciente utiliza os filtros de data e especialidade médica na seção de histórico
+Então o sistema mostra apenas as consultas que atendem aos critérios selecionados.

+
+ +

User Story:

+
    +
  • Código: US07

    +Como Paciente
    +Eu quero acessar as informações dos meus medicamentos
    +Para que eu possa entender as orientações de uso, dosagem, efeitos colaterais e manter o controle do meu tratamento. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Acessar lista de medicamentos prescritos
+

Dado que o paciente está autenticado no sistema
+Quando o paciente acessa a seção de medicamentos
+Então o sistema exibe uma lista de todos os medicamentos prescritos, com nome, dosagem e frequência de uso.

+
Cenário 2: Visualizar detalhes de um medicamento específico
+

Dado que o paciente está visualizando a lista de medicamentos
+Quando o paciente seleciona um medicamento específico
+Então o sistema exibe os detalhes completos, incluindo as instruções de uso, possíveis efeitos colaterais, interações medicamentosas e precauções.

+
Cenário 3: Verificar orientações de uso e horários de administração
+

Dado que o paciente está acessando os detalhes de um medicamento
+Quando visualiza as orientações de uso
+Então o sistema apresenta as instruções detalhadas sobre como tomar o medicamento, incluindo horários recomendados e se deve ser tomado com ou sem alimentos.

+
Cenário 4: Receber notificações de horários para tomar o medicamento
+

Dado que o paciente tem um medicamento com horários específicos de administração
+Quando a hora de tomar o medicamento estiver próxima
+Então o sistema envia uma notificação para o paciente, lembrando-o de tomar o medicamento no horário certo.

+
Cenário 5: Acessar alertas de interações medicamentosas
+

Dado que o paciente está visualizando a lista de medicamentos
+Quando há uma interação medicamentosa entre os remédios prescritos
+Então o sistema exibe um alerta informando sobre as interações e recomenda cuidados específicos ou consultas com o médico.

+
Cenário 6: Consultar histórico de uso de medicamentos
+

Dado que o paciente deseja revisar quais medicamentos foram usados no passado
+Quando acessa a seção de histórico de medicamentos
+Então o sistema exibe uma lista de medicamentos anteriores com datas de prescrição, uso e término do tratamento.

+
Cenário 7: Verificar contraindicações e avisos especiais
+

Dado que o paciente está acessando os detalhes de um medicamento
+Quando revisa as informações de segurança
+Então o sistema destaca contraindicações, avisos especiais para gestantes, lactantes, e possíveis alergias.

+
+ +

User Story:

+
    +
  • Código: US08

    +Como Paciente
    +Eu quero solicitar o agendamento de consultas
    +Para que eu possa marcar atendimentos médicos de maneira conveniente, sem precisar ligar ou comparecer fisicamente à clínica.
    +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Solicitar agendamento de consulta via sistema
+

Dado que o paciente está autenticado no sistema
+Quando o paciente acessa a seção de agendamento de consultas
+E seleciona a especialidade médica, data e horário desejados
+Então o sistema exibe as opções de horários disponíveis
+E permite que o paciente finalize a solicitação de agendamento.

+
Cenário 2: Receber confirmação da solicitação de agendamento
+

Dado que o paciente solicitou o agendamento de uma consulta
+Quando a solicitação é processada pelo sistema
+Então o paciente recebe uma notificação de confirmação com os detalhes da consulta agendada
+E um e-mail ou SMS é enviado com as informações da consulta.

+
Cenário 3: Visualizar disponibilidade de horários para consultas
+

Dado que o paciente deseja agendar uma consulta
+Quando o paciente seleciona a especialidade médica e o médico desejado
+Então o sistema exibe um calendário com os horários disponíveis para consulta
+E permite que o paciente escolha a melhor data e horário.

+
Cenário 4: Receber alerta sobre indisponibilidade de horários
+

Dado que o paciente solicitou um agendamento em uma data e horário específico
+Quando não há horários disponíveis para a consulta selecionada
+Então o sistema notifica o paciente sobre a indisponibilidade
+E sugere horários alternativos ou a possibilidade de adicionar o paciente a uma lista de espera.

+
Cenário 5: Cancelar ou reagendar consulta solicitada
+

Dado que o paciente tem uma consulta previamente agendada
+Quando o paciente acessa a seção de consultas agendadas
+Então o sistema exibe a opção de cancelar ou reagendar a consulta
+E permite que o paciente selecione um novo horário, caso necessário.

+
+ +

User Story:

+
    +
  • Código: US09

    +Como Paciente
    +Eu quero visualizar os agendamentos das minhas consultas
    +Para que eu possa acompanhar meus compromissos médicos e gerenciar meu calendário de forma eficiente. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Visualizar lista de consultas agendadas
+

Dado que o paciente está autenticado no sistema
+Quando o paciente acessa a seção de consultas agendadas
+Então o sistema exibe uma lista de todas as consultas futuras marcadas, com detalhes como data, horário, médico, e local da consulta.

+
Cenário 2: Identificar consultas próximas
+

Dado que o paciente está visualizando as consultas agendadas
+Quando a data da consulta estiver próxima (por exemplo, em 24 horas)
+Então o sistema destaca a consulta com um alerta visual
+E envia uma notificação ao paciente para lembrá-lo do compromisso.

+
Cenário 3: Visualizar status de aprovação ou pendência de consulta
+

Dado que o paciente está visualizando suas consultas
+Quando uma consulta estiver pendente de aprovação (por exemplo, aguardando confirmação do médico)
+Então o sistema exibe o status atual da consulta e as ações possíveis.

+
+ +

User Story:

+
    +
  • Código: US10

    +Como Paciente
    +Eu quero ser alertado sobre a proximidade da data da minha consulta
    +Para que eu possa me preparar adequadamente e evitar esquecimentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Receber alerta de consulta com 24 horas de antecedência
+

Dado que o paciente tem uma consulta marcada para o dia seguinte
+Quando a consulta estiver a menos de 24 horas de ocorrer
+Então o sistema envia uma notificação para o paciente informando a data, hora, e local da consulta.

+
Cenário 2: Receber alerta de consulta com 1 hora de antecedência
+

Dado que o paciente tem uma consulta marcada para o mesmo dia
+Quando a consulta estiver a menos de 1 hora de ocorrer
+Então o sistema envia um alerta urgente ao paciente, reforçando o horário e as instruções de chegada.

+
Cenário 3: Alerta de consulta reagendada ou alterada
+

Dado que a consulta do paciente foi reagendada ou teve alterações
+Quando o sistema enviar o alerta de proximidade
+Então o sistema destaca que houve uma alteração no horário ou data, evitando que o paciente vá em horários errados.

+
Cenário 4: Alerta de falta de confirmação do paciente
+

Dado que o paciente precisa confirmar presença na consulta
+Quando o sistema identificar que a confirmação ainda não foi feita
+Então o alerta inclui um pedido de confirmação para garantir o comparecimento.

+
+ +

4.4. PERSONA 4 - COORDENADOR DE AGENDAMENTO

+

User Story:

+
    +
  • Código: US11

    +Como Coordenador de Agendamento
    +Eu quero visualizar a disponibilidade de datas e horários na agenda de médicos e especialistas
    +Para que eu possa agendar consultas de forma eficiente, evitando conflitos e melhorando a organização das agendas. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Visualizar disponibilidade em calendário mensal
+

Dado que o sistema possui um calendário mensal para cada médico e especialista
+Quando o Coordenador de Agendamento acessa a visualização da agenda de um médico
+Então o sistema exibe um calendário mensal com os dias e horários disponíveis e ocupados, permitindo ao coordenador ver rapidamente a disponibilidade para o mês.

+
Cenário 2: Visualizar disponibilidade em calendário semanal
+

Dado que o sistema possui um calendário semanal para cada médico e especialista
+Quando o Coordenador de Agendamento acessa a visualização da agenda de um especialista
+Então o sistema exibe um calendário semanal detalhado com os horários disponíveis e ocupados para a semana atual, facilitando o agendamento imediato.

+
Cenário 3: Filtro por especialidade
+

Dado que o sistema possui médicos e especialistas com diferentes especialidades
+Quando o Coordenador de Agendamento aplica um filtro por especialidade
+Então o sistema exibe a disponibilidade apenas dos médicos e especialistas com a especialidade selecionada, ajudando a encontrar a disponibilidade de acordo com a necessidade do paciente.

+
Cenário 4: Visualização da disponibilidade por período específico
+

Dado que o Coordenador de Agendamento precisa visualizar a disponibilidade para um período específico
+Quando ele solicita a visualização para um intervalo de datas específico
+Então o sistema exibe a disponibilidade dos médicos e especialistas apenas para o período selecionado, facilitando a busca por horários disponíveis dentro desse intervalo.

+
+ +

User Story:

+
    +
  • Código: US12

    +Como Coordenador de Agendamento
    +Eu quero reservar agendamentos de consultas na agenda de médicos e especialistas
    +Para que eu possa garantir que os pacientes sejam atendidos conforme a disponibilidade dos profissionais e evitar conflitos de horário. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Reservar uma consulta para um paciente
+

Dado que o sistema exibe a disponibilidade de médicos e especialistas
+Quando o Coordenador de Agendamento seleciona um horário disponível e insere as informações do paciente
+Então o sistema reserva o horário para o paciente e atualiza a agenda do médico ou especialista, confirmando a reserva com um aviso ao paciente e ao profissional.

+
Cenário 2: Confirmar reserva com o paciente
+

Dado que a reserva de uma consulta foi feita com sucesso
+Quando o sistema finaliza a reserva
+Então o paciente recebe uma confirmação de agendamento por e-mail ou SMS, contendo a data, hora e o local da consulta, e o médico ou especialista também é notificado.

+
Cenário 3: Ajustar a reserva existente
+

Dado que uma consulta foi previamente agendada e precisa ser ajustada
+Quando o Coordenador de Agendamento seleciona o agendamento existente e altera a data ou o horário
+Então o sistema atualiza a reserva, notificando tanto o paciente quanto o médico ou especialista sobre a nova data e hora da consulta.

+
Cenário 4: Cancelar uma reserva
+

Dado que uma consulta agendada precisa ser cancelada
+Quando o Coordenador de Agendamento seleciona o agendamento e confirma o cancelamento
+Então o sistema remove o horário da agenda do médico ou especialista e notifica o paciente sobre o cancelamento, permitindo que ele reaja a nova disponibilidade.

+
Cenário 5: Evitar conflitos de horário
+

Dado que o Coordenador de Agendamento está reservando um horário
+Quando ele seleciona um horário disponível
+Então o sistema verifica automaticamente se há algum conflito com outros agendamentos e alerta o coordenador se o horário já estiver reservado ou se ocorrer um conflito.

+
+ +

User Story:

+
    +
  • Código: US13

    +Como Coordenador de Agendamento
    +Eu quero receber alertas sobre cancelamentos de consultas
    +Para que eu possa rapidamente reagendar os horários e informar tanto os pacientes quanto os médicos ou especialistas sobre as mudanças, minimizando o impacto dos cancelamentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Receber alerta de cancelamento de consulta
+

Dado que um paciente cancela uma consulta
+Quando o cancelamento é registrado no sistema
+Então o Coordenador de Agendamento recebe um alerta imediato sobre o cancelamento, com detalhes da consulta e informações do paciente.

+
Cenário 2: Atualizar a agenda com o horário liberado
+

Dado que um horário foi cancelado
+Quando o Coordenador de Agendamento recebe o alerta
+Então o sistema atualiza a agenda do médico ou especialista para refletir a disponibilidade do horário cancelado, tornando-o visível para novos agendamentos.

+

4.5. PERSONA 5 - FARMACÊUTICA

+

User Story:

+
    +
  • Código: US14

    +Como Farmacêutica
    +Eu quero registrar a entrada de medicamentos no estoque
    +Para que eu possa monitorar e gerenciar o inventário de medicamentos de forma eficaz, garantindo que a farmácia tenha todos os medicamentos necessários e evitando faltas ou excessos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Registrar a entrada de medicamentos no sistema
+

Dado que um novo lote de medicamentos chegou à farmácia
+Quando a Farmacêutica recebe o lote
+Então ela acessa o sistema de gerenciamento de estoque e registra a entrada dos medicamentos, incluindo detalhes como nome, quantidade, data de validade e número do lote.

+
Cenário 2: Verificar se o medicamento já está registrado
+

Dado que a Farmacêutica está registrando um medicamento
+Quando o medicamento já existe no sistema
+Então o sistema verifica e atualiza a quantidade disponível no estoque existente, ao invés de criar um novo registro, e notifica a Farmacêutica sobre a atualização.

+
Cenário 3: Receber alerta de validade próxima
+

Dado que um medicamento foi registrado no sistema
+Quando a data de validade está próxima
+Então o sistema envia um alerta à Farmacêutica sobre o medicamento, destacando a necessidade de uso ou descarte iminente para evitar perdas.

+
Cenário 4: Confirmar a entrada de medicamentos
+

Dado que a Farmacêutica registrou a entrada de medicamentos
+Quando a entrada é registrada
+Então o sistema confirma a operação e atualiza a quantidade total de medicamentos no estoque, gerando um recibo digital de entrada.

+
Cenário 5: Validar informações de medicamentos
+

Dado que a Farmacêutica está registrando novos medicamentos
+Quando as informações do medicamento são inseridas
+Então o sistema valida os dados para garantir que todas as informações obrigatórias estejam completas e corretas, e notifica a Farmacêutica caso haja algum erro ou informação faltante.

+
Cenário 6: Atualizar quantidade de medicamentos no estoque
+

Dado que o medicamento foi registrado
+Quando a quantidade registrada é confirmada
+Então o sistema atualiza o estoque de medicamentos com a nova quantidade e ajusta os níveis disponíveis, garantindo precisão no gerenciamento do inventário.

+
+ +

User Story:

+
    +
  • Cenário: US15

    +Como Farmacêutica
    +Eu quero registrar a saída de medicamentos no estoque
    +Para que eu possa monitorar e gerenciar o inventário de medicamentos de forma eficaz, garantindo que o estoque esteja sempre refletindo a quantidade correta disponível e evitando problemas de falta ou excesso de medicamentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Registrar a saída de medicamentos para um paciente
+

Dado que um medicamento foi dispensado para um paciente
+Quando a Farmacêutica processa a saída
+Então ela acessa o sistema de gerenciamento de estoque e registra a saída do medicamento, incluindo detalhes como nome, quantidade, data e número da receita, se aplicável.

+
Cenário 2: Atualizar a quantidade disponível no estoque
+

Dado que a Farmacêutica registrou a saída de um medicamento
+Quando a saída é registrada
+Então o sistema atualiza a quantidade disponível no estoque, refletindo a nova quantidade após a saída do medicamento.

+
Cenário 3: Validar a quantidade registrada para saída
+

Dado que a Farmacêutica está registrando a saída de medicamentos
+Quando a quantidade registrada é maior do que a disponível no estoque
+Então o sistema exibe uma mensagem de erro e impede o registro até que a quantidade correta seja inserida, garantindo a precisão do inventário.

+
Cenário 4: Receber alerta de baixo estoque
+

Dado que a saída de um medicamento é registrada
+Quando a quantidade disponível atinge um nível crítico
+Então o sistema envia um alerta para a Farmacêutica indicando que o estoque do medicamento está baixo e precisa ser reabastecido.

+
+ +

User Story:

+
    +
  • Código: US16

    +Como Farmacêutica
    +Eu quero buscar os medicamentos existentes no estoque
    +Para que eu possa verificar a disponibilidade e localização dos medicamentos, facilitar o atendimento ao paciente e garantir uma gestão eficiente do inventário. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Buscar medicamento pelo nome
+

Dado que a Farmacêutica deseja buscar um medicamento específico
+Quando ela insere o nome do medicamento na função de busca do sistema
+Então o sistema exibe uma lista de medicamentos correspondentes, incluindo detalhes como quantidade disponível, localização no estoque e data de validade. +

+
Cenário 2: Buscar medicamento por código de barras
+

Dado que a Farmacêutica tem o código de barras do medicamento
+Quando ela escaneia ou insere o código de barras no sistema de busca
+Então o sistema retorna as informações detalhadas sobre o medicamento, incluindo a quantidade disponível e localização no estoque.

+
Cenário 3: Buscar medicamentos por categoria
+

Dado que a Farmacêutica precisa verificar medicamentos em uma categoria específica
+Quando ela seleciona a categoria desejada no sistema de busca
+Então o sistema exibe todos os medicamentos pertencentes à categoria selecionada, com detalhes sobre a quantidade disponível e localização no estoque.

+
Cenário 4: Buscar medicamentos próximos da data de validade
+

Dado que a Farmacêutica deseja verificar medicamentos próximos da data de validade
+Quando ela solicita a busca por medicamentos com validade próxima
+Então o sistema exibe uma lista de medicamentos cuja data de validade está prestes a expirar, permitindo à Farmacêutica tomar ações apropriadas para evitar desperdício e garantir a segurança dos pacientes.

+
Cenário 5: Buscar medicamentos com baixa quantidade
+

Dado que a Farmacêutica precisa verificar medicamentos com estoque baixo
+Quando ela solicita a busca por medicamentos com quantidade abaixo de um nível pré-definido
+Então o sistema exibe uma lista de medicamentos que estão com estoque baixo, facilitando o reabastecimento e a gestão de inventário.

+
Cenário 6: Buscar medicamentos por fornecedor
+

Dado que a Farmacêutica deseja verificar os medicamentos fornecidos por um fornecedor específico
+Quando ela seleciona o fornecedor desejado no sistema de busca
+Então o sistema exibe todos os medicamentos que foram fornecidos pelo fornecedor selecionado, incluindo a quantidade disponível e localização no estoque.

+
+ +

User Story:

+
    +
  • Código: US17

    +Como Farmacêutica
    +Eu quero visualizar os medicamentos prescritos para o paciente
    +Para que eu possa garantir que o paciente receba a medicação correta, verificar a conformidade com a prescrição e identificar possíveis interações medicamentosas. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Visualizar medicamentos prescritos em uma única prescrição
+

Dado que a Farmacêutica deseja verificar os medicamentos prescritos em uma prescrição específica
+Quando ela seleciona a prescrição do paciente no sistema
+Então o sistema exibe uma lista detalhada dos medicamentos prescritos, incluindo nome, dosagem, frequência e duração do tratamento.

+
Cenário 2: Visualizar medicamentos prescritos para um paciente específico
+

Dado que a Farmacêutica precisa revisar todos os medicamentos prescritos para um paciente
+Quando ela busca o paciente no sistema
+Então o sistema exibe uma lista completa de todas as prescrições atuais e passadas, incluindo os medicamentos prescritos, dosagem e datas.

+
Cenário 3: Visualizar medicamentos prescritos com informações sobre interações
+

Dado que a Farmacêutica está revisando medicamentos prescritos para um paciente
+Quando ela acessa a prescrição no sistema
+Então o sistema fornece informações sobre possíveis interações medicamentosas entre os medicamentos prescritos, ajudando a prevenir reações adversas.

+
+ +

User Story:

+
    +
  • Código: US18

    +Como Farmacêutica
    +Eu quero registrar os detalhes de efeitos adversos da medicação
    +Para que eu possa monitorar e gerenciar reações indesejadas, garantir a segurança dos pacientes e atualizar o histórico de medicação com informações importantes para futuras prescrições. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Registrar efeitos adversos de uma medicação específica
+

Dado que a Farmacêutica deseja registrar efeitos adversos para uma medicação específica
+Quando ela seleciona a medicação no sistema e insere os detalhes dos efeitos adversos observados
+Então o sistema deve registrar os detalhes e associá-los à medicação, incluindo informações sobre a gravidade, a data e a descrição dos sintomas.

+
Cenário 2: Registrar múltiplos efeitos adversos para uma medicação
+

Dado que foram observados vários efeitos adversos para uma única medicação
+Quando a Farmacêutica insere múltiplos detalhes de efeitos adversos no sistema
+Então o sistema deve permitir a entrada de múltiplos efeitos adversos, associando cada um à medicação e fornecendo uma visão consolidada de todos os efeitos observados.

+
+ +

User Story:

+
    +
  • Código: US19
    +Como Farmacêutica +Eu quero registrar os dias e horários para medicação conforme a prescrição do paciente
    +Para que eu possa garantir que a medicação seja administrada corretamente e ajudar o paciente a seguir o regime de tratamento conforme prescrito. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Registrar dias e horários para uma medicação específica
+

Dado que a Farmacêutica está no processo de registrar a medicação para um paciente
+Quando ela insere os dias e horários específicos para a administração da medicação conforme a prescrição
+Então o sistema deve registrar essas informações associadas à medicação e ao paciente, e exibir uma confirmação da entrada bem-sucedida.

+
Cenário 2: Atualizar dias e horários registrados para uma medicação
+

Dado que houve uma alteração nos dias e horários para a medicação de um paciente
+Quando a Farmacêutica atualiza os dias e horários no sistema
+Então o sistema deve atualizar as informações registradas e fornecer uma confirmação de que os detalhes foram modificados com sucesso.

+
Cenário 3: Registrar medicação com múltiplas administrações diárias
+

Dado que um paciente deve tomar a medicação várias vezes ao dia
+Quando a Farmacêutica insere os horários específicos para cada administração diária
+Então o sistema deve permitir a entrada de múltiplos horários para a mesma medicação e garantir que todas as entradas sejam corretamente associadas ao paciente.

+
Cenário 4: Visualizar dias e horários registrados para medicação
+

Dado que a Farmacêutica precisa revisar os dias e horários registrados para a medicação de um paciente
+Quando ela acessa a visualização de medicações e horários no sistema
+Então o sistema deve exibir uma lista clara e completa dos dias e horários programados para a administração da medicação, permitindo a confirmação e verificação dos dados.

+
+ +

User Story:

+
    +
  • Código: US20

    +Como Farmacêutica
    +
    Eu quero registrar a categoria de tarja da medicação
    +
    Para que** eu possa classificar corretamente as medicações e garantir o controle adequado dos medicamentos, além de seguir as regulamentações e requisitos de segurança. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Registrar uma medicação com uma nova categoria de tarja
+

Dado que a Farmacêutica está registrando uma nova medicação
+Quando ela insere a categoria de tarja apropriada para a medicação
+Então o sistema deve armazenar a categoria de tarja junto com as informações da medicação e confirmar que o registro foi realizado com sucesso.

+
Cenário 2: Atualizar a categoria de tarja de uma medicação existente
+

Dado que a Farmacêutica precisa alterar a categoria de tarja de uma medicação já registrada
+Quando ela atualiza a categoria de tarja no sistema
+Então o sistema deve refletir a nova categoria de tarja e fornecer uma confirmação de que a alteração foi bem-sucedida.

+
Cenário 3: Registrar medicação sem categoria de tarja especificada
+

Dado que uma medicação está sendo registrada e não possui uma categoria de tarja especificada
+Quando a Farmacêutica tenta salvar o registro sem fornecer a categoria de tarja
+Então o sistema deve exibir uma mensagem de erro informando que a categoria de tarja é obrigatória e solicitar que a Farmacêutica forneça a informação necessária.

+
+ +

User Story:

+
    +
  • Código: US21

    +Como Farmacêutica
    +Eu quero editar os efeitos adversos da medicação
    +Para que eu possa garantir que as informações sobre a medicação estejam atualizadas e precisas, ajudando na segurança e no controle adequado dos medicamentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Editar efeitos adversos de uma medicação existente
+

Dado que a Farmacêutica precisa atualizar os efeitos adversos de uma medicação já registrada
+Quando ela acessa a medicação e modifica a descrição dos efeitos adversos
+Então o sistema deve salvar as alterações e confirmar que a atualização foi bem-sucedida, refletindo as novas informações no registro da medicação.

+
Cenário 2: Reverter alterações nos efeitos adversos
+

Dado que a Farmacêutica fez uma alteração nos efeitos adversos que precisa ser revertida
+Quando ela seleciona a opção de reverter para a versão anterior dos efeitos adversos
+Então o sistema deve restaurar a descrição dos efeitos adversos para o estado anterior e confirmar que a reversão foi concluída com sucesso.

+
+ +

User Story:

+
    +
  • Código: US22

    +Como Farmacêutica
    +Eu quero registrar detalhes adicionais da medicação
    +Para que eu possa garantir que todas as informações relevantes e úteis sobre a medicação estejam disponíveis e atualizadas, ajudando na gestão e controle eficiente dos medicamentos. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Adicionar detalhes adicionais a uma medicação existente
+

Dado que a Farmacêutica deseja adicionar mais informações a uma medicação já registrada
+Quando ela acessa o registro da medicação e insere detalhes adicionais
+Então o sistema deve atualizar o registro da medicação com as novas informações e confirmar que a atualização foi concluída.

+
Cenário 2: Editar detalhes adicionais de uma medicação
+

Dado que a Farmacêutica está revisando os detalhes adicionais de uma medicação
+Quando ela modifica ou corrige as informações já registradas
+Então o sistema deve salvar as alterações e confirmar que os detalhes adicionais foram atualizados, refletindo as mudanças no registro da medicação.

+
Cenário 3: Visualizar detalhes adicionais registrados
+

Dado que a Farmacêutica deseja revisar os detalhes adicionais de uma medicação
+Quando ela acessa o registro da medicação
+Então o sistema deve exibir todos os detalhes adicionais registrados, permitindo a visualização completa e clara das informações sobre a medicação.

+
+ +

4.6. PERSONA 6 - DIRETOR DE TECNOLOGIA

+

User Story:

+
    +
  • Código: US23

    +Como Diretor de Tecnologia
    +Eu quero gerar relatórios baseados na quantidade de erros de software
    +Para que eu possa analisar a qualidade do sistema, identificar áreas problemáticas e tomar decisões informadas para melhorias. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Gerar relatório de erros por categoria
+

Dado que o sistema tem erros classificados em diferentes categorias (ex: bugs, falhas de segurança, problemas de desempenho)
+Quando o Diretor de Tecnologia solicita um relatório de erros
+Então o sistema gera um relatório detalhado, mostrando a quantidade de erros por categoria.

+
Cenário 2: Gerar relatório de erros por data
+

Dado que o sistema registra erros com timestamps
+Quando o Diretor de Tecnologia solicita um relatório de erros para um intervalo de datas específico
+Então o sistema gera um relatório mostrando a quantidade de erros ocorridos dentro desse intervalo de datas.

+
Cenário 3: Gerar relatório de erros por gravidade
+

Dado que os erros são classificados por níveis de gravidade (ex: crítico, alto, médio, baixo)
+Quando o Diretor de Tecnologia solicita um relatório de erros
+Então o sistema gera um relatório detalhado, mostrando a quantidade de erros por nível de gravidade.

+
Cenário 4: Gerar relatório comparativo de erros
+

Dado que o sistema armazena dados de erros ao longo do tempo
+Quando o Diretor de Tecnologia solicita um relatório comparativo
+Então o sistema gera um relatório que compara a quantidade de erros em diferentes períodos (mensal, trimestral, anual) para identificar tendências e melhorias.

+
Cenário 5: Gerar relatório de erros por módulo ou funcionalidade
+

Dado que os erros estão associados a diferentes módulos ou funcionalidades do sistema
+Quando o Diretor de Tecnologia solicita um relatório de erros
+Então o sistema gera um relatório mostrando a quantidade de erros por módulo ou funcionalidade, permitindo identificar áreas que precisam de atenção.

+
Cenário 6: Relatório com detalhes dos erros
+

Dado que os erros são registrados com detalhes específicos (ex: mensagem de erro, stack trace, usuário afetado)
+Quando o Diretor de Tecnologia solicita um relatório de erros
+Então o sistema gera um relatório detalhado que inclui as informações completas sobre cada erro registrado.

+
Cenário 7: Exportar relatório em diferentes formatos
+

Dado que o sistema permite exportação de relatórios
+Quando o Diretor de Tecnologia solicita um relatório de erros
+Então o sistema gera e exporta o relatório em diferentes formatos (ex: PDF, Excel, CSV) conforme a necessidade do Diretor.

+
Cenário 8: Agendar geração de relatórios automáticos
+

Dado que o Diretor de Tecnologia precisa de relatórios regulares
+Quando ele configurar uma agenda para a geração de relatórios
+Então o sistema gera e envia automaticamente os relatórios conforme a frequência configurada (diária, semanal, mensal).

+
+ +

User Story:

+
    +
  • Código: US24

    +Como Diretor de Tecnologia
    +Eu quero gerar relatórios baseados na taxa de performance
    +Para que eu possa avaliar o desempenho do sistema, identificar áreas que precisam de otimização e tomar decisões informadas para melhorar a eficiência. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Gerar relatório de performance por módulo
+

Dado que o sistema possui vários módulos com diferentes taxas de performance
+Quando o Diretor de Tecnologia solicita um relatório de performance
+Então o sistema gera um relatório detalhado mostrando a taxa de performance de cada módulo, incluindo métricas como tempo de resposta e uso de recursos.

+
Cenário 2: Gerar relatório de performance por período
+

Dado que o sistema registra dados de performance ao longo do tempo
+Quando o Diretor de Tecnologia solicita um relatório de performance para um intervalo de datas específico
+Então o sistema gera um relatório mostrando a taxa de performance durante o intervalo solicitado, com gráficos e métricas relevantes.

+
Cenário 3: Gerar relatório de performance por funcionalidade
+

Dado que o sistema possui várias funcionalidades com diferentes taxas de performance
+Quando o Diretor de Tecnologia solicita um relatório de performance
+Então o sistema gera um relatório detalhado mostrando a taxa de performance de cada funcionalidade, permitindo identificar quais funcionalidades estão impactando o desempenho.

+
Cenário 4: Relatório comparativo de performance
+

Dado que o sistema armazena dados de performance em diferentes períodos
+Quando o Diretor de Tecnologia solicita um relatório comparativo
+Então o sistema gera um relatório que compara a taxa de performance entre diferentes períodos (mensal, trimestral, anual) para identificar tendências e mudanças no desempenho.

+
Cenário 5: Relatório de performance por tipo de usuário
+

Dado que o sistema coleta dados de performance com base no tipo de usuário (administrador, usuário comum, etc.)
+Quando o Diretor de Tecnologia solicita um relatório de performance
+Então o sistema gera um relatório mostrando a taxa de performance para cada tipo de usuário, identificando possíveis discrepâncias no desempenho entre diferentes grupos de usuários.

+
Cenário 6: Relatório com detalhes de performance
+

Dado que o sistema registra detalhes específicos de performance (ex: tempos de resposta, uso de CPU, memória)
+Quando o Diretor de Tecnologia solicita um relatório de performance
+Então o sistema gera um relatório detalhado que inclui informações completas sobre o desempenho do sistema, como tempos de resposta e uso de recursos.

+
Cenário 7: Exportar relatório em diferentes formatos
+

Dado que o sistema permite exportação de relatórios
+Quando o Diretor de Tecnologia solicita um relatório de performance
+Então o sistema gera e exporta o relatório em diferentes formatos (ex: PDF, Excel, CSV) conforme a necessidade do Diretor.

+
Cenário 8: Agendar geração de relatórios automáticos
+

Dado que o Diretor de Tecnologia precisa de relatórios regulares sobre performance
+Quando ele configurar uma agenda para a geração de relatórios
+Então o sistema gera e envia automaticamente os relatórios conforme a frequência configurada (diária, semanal, mensal).

+
+ +

User Story:

+
    +
  • Código: US25

    +Como Diretor de Tecnologia
    +Eu quero gerar relatórios baseados na taxa de segurança
    +Para que eu possa monitorar a segurança do sistema, identificar vulnerabilidades e garantir que as medidas de segurança estejam funcionando adequadamente. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Gerar relatório de segurança por tipo de ameaça
+

Dado que o sistema registra diferentes tipos de ameaças e incidentes de segurança
+Quando o Diretor de Tecnologia solicita um relatório de segurança
+Então o sistema gera um relatório detalhado mostrando a taxa de segurança para cada tipo de ameaça (ex: ataques de SQL injection, tentativas de phishing, vulnerabilidades detectadas).

+
Cenário 2: Gerar relatório de segurança por período
+

Dado que o sistema armazena dados de segurança ao longo do tempo
+Quando o Diretor de Tecnologia solicita um relatório de segurança para um intervalo de datas específico
+Então o sistema gera um relatório mostrando a taxa de segurança durante o intervalo solicitado, incluindo gráficos e métricas relevantes.

+
Cenário 3: Gerar relatório de segurança por módulo do sistema
+

Dado que o sistema possui diferentes módulos com níveis variados de segurança
+Quando o Diretor de Tecnologia solicita um relatório de segurança
+Então o sistema gera um relatório detalhado mostrando a taxa de segurança de cada módulo, permitindo identificar quais módulos têm maiores vulnerabilidades.

+
Cenário 4: Relatório comparativo de segurança
+

Dado que o sistema registra dados de segurança em diferentes períodos
+Quando o Diretor de Tecnologia solicita um relatório comparativo
+Então o sistema gera um relatório que compara a taxa de segurança entre diferentes períodos (mensal, trimestral, anual) para identificar tendências e melhorias na segurança.

+
Cenário 5: Relatório de incidentes de segurança
+

Dado que o sistema registra todos os incidentes de segurança
+Quando o Diretor de Tecnologia solicita um relatório de incidentes
+Então o sistema gera um relatório detalhado sobre os incidentes de segurança ocorridos, incluindo a gravidade, a resposta e o impacto de cada incidente.

+
Cenário 6: Relatório de conformidade com normas de segurança
+

Dado que o sistema precisa estar em conformidade com normas e regulamentações de segurança (ex: GDPR, HIPAA)
+Quando o Diretor de Tecnologia solicita um relatório de conformidade
+Então o sistema gera um relatório que mostra a conformidade com as normas de segurança e identifica áreas onde a conformidade pode ser melhorada.

+
Cenário 7: Relatório de vulnerabilidades identificadas
+

Dado que o sistema realiza varreduras de segurança para identificar vulnerabilidades
+Quando o Diretor de Tecnologia solicita um relatório de vulnerabilidades
+Então o sistema gera um relatório detalhado sobre as vulnerabilidades identificadas, incluindo informações sobre a severidade e o status da correção.

+
Cenário 8: Exportar relatório de segurança em diferentes formatos
+

Dado que o sistema permite exportação de relatórios
+Quando o Diretor de Tecnologia solicita um relatório de segurança
+Então o sistema gera e exporta o relatório em diferentes formatos (ex: PDF, Excel, CSV) conforme a necessidade do Diretor.

+
Cenário 9: Agendar geração de relatórios de segurança automáticos
+

Dado que o Diretor de Tecnologia precisa de relatórios regulares sobre segurança
+Quando ele configurar uma agenda para a geração de relatórios
+Então o sistema gera e envia automaticamente os relatórios conforme a frequência configurada (diária, semanal, mensal).

+
+ +

User Story:

+
    +
  • Código: US26

    +Como Diretor de Tecnologia
    +Eu quero gerar relatórios baseados na taxa de utilização
    +Para que eu possa monitorar o uso dos recursos do sistema, identificar padrões de utilização e áreas que podem precisar de otimização ou aumento de capacidade. +

  • +
+

Critérios de Aceitação no Formato BDD:

+
Cenário 1: Gerar relatório de utilização por módulo
+

Dado que o sistema possui diferentes módulos com níveis variados de utilização
+Quando o Diretor de Tecnologia solicita um relatório de utilização
+Então o sistema gera um relatório detalhado mostrando a taxa de utilização de cada módulo, permitindo identificar quais módulos estão mais ou menos utilizados.

+
Cenário 2: Gerar relatório de utilização por período
+

Dado que o sistema armazena dados de utilização ao longo do tempo
+Quando o Diretor de Tecnologia solicita um relatório de utilização para um intervalo de datas específico
+Então o sistema gera um relatório mostrando a taxa de utilização durante o intervalo solicitado, incluindo gráficos e métricas relevantes.

+
Cenário 3: Relatório comparativo de utilização
+

Dado que o sistema registra dados de utilização em diferentes períodos
+Quando o Diretor de Tecnologia solicita um relatório comparativo
+Então o sistema gera um relatório que compara a taxa de utilização entre diferentes períodos (mensal, trimestral, anual) para identificar tendências e mudanças no padrão de utilização.

+
Cenário 4: Relatório de utilização por usuário
+

Dado que o sistema registra a utilização por usuário
+Quando o Diretor de Tecnologia solicita um relatório de utilização
+Então o sistema gera um relatório mostrando a taxa de utilização por usuário, permitindo identificar quais usuários estão mais ou menos ativos.

+
Cenário 5: Relatório de utilização de recursos críticos
+

Dado que o sistema possui recursos críticos cuja utilização precisa ser monitorada
+Quando o Diretor de Tecnologia solicita um relatório de utilização
+Então o sistema gera um relatório detalhado mostrando a taxa de utilização de recursos críticos, como servidores, banco de dados, e redes, permitindo identificar gargalos e áreas que precisam de mais capacidade.

+
Cenário 6: Exportar relatório de utilização em diferentes formatos
+

Dado que o sistema permite exportação de relatórios
+Quando o Diretor de Tecnologia solicita um relatório de utilização
+Então o sistema gera e exporta o relatório em diferentes formatos (ex: PDF, Excel, CSV) conforme a necessidade do Diretor.

+
Cenário 7: Agendar geração de relatórios de utilização automáticos
+

Dado que o Diretor de Tecnologia precisa de relatórios regulares sobre utilização
+Quando ele configurar uma agenda para a geração de relatórios
+Então o sistema gera e envia automaticamente os relatórios conforme a frequência configurada (diária, semanal, mensal).

+

5. Referências

+
+

JONES, Roberto. PBB: Product Backlog Building. Medium, 02 Mar. 2022. Disponível em: https://medium.com/@jonesroberto/pbb-product-backlog-building-0012a7a5256a.

+
+

Histórico de Revisão

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoDaniel RodriguesJoyce Dionizio
08/09/241.1Atualizacao do documentoDaniel RodriguesJésus Gabriel
09/09/241.2Atualizacao do BDDDaniel RodriguesJésus Gabriel
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/entregas/unidade3/usm/index.html b/sections/entregas/unidade3/usm/index.html new file mode 100644 index 00000000..3cca89bf --- /dev/null +++ b/sections/entregas/unidade3/usm/index.html @@ -0,0 +1,1508 @@ + + + + + + + + + + + + + + + + + + + + + + + Missão 3 | USM - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Missão 3 - USM

+

1. User Story Mapping (USM)

+

User Story Mapping (USM) é uma técnica de planejamento e desenvolvimento de produtos que permite visualizar o processo do ponto de vista dos usuários. Através do mapeamento de histórias de usuário, as equipes podem identificar as principais atividades e tarefas que os usuários desejam realizar, ajudando a priorizar funcionalidades e criar uma visão compartilhada do produto. USM é particularmente útil para entender as necessidades dos usuários, alinhar a equipe de desenvolvimento e definir o escopo para as diferentes versões do produto.

+

2. Beneficios do USM

+

Para a ComunEventos, o USM desempenha um papel crucial ao garantir que a plataforma seja desenvolvida de forma a atender efetivamente às necessidades de seus diversos usuários, que incluem organizadores de eventos, participantes, fornecedores, patrocinadores e voluntários. Ao mapear essas necessidades, a ComunEventos pode:

+
    +
  • Identificar Funcionalidades Prioritárias: Concentrar-se nas funcionalidades que trazem maior valor no curto prazo, como parte de um MVP, garantindo um lançamento eficiente e direcionado.
  • +
  • Alinhar Expectativas: Criar uma visão clara e compartilhada entre todos os membros da equipe de desenvolvimento e stakeholders sobre o que é mais importante para o produto.
  • +
  • Melhorar a Experiência do Usuário: Proporcionar uma experiência mais intuitiva e integrada para todos os usuários da plataforma, aumentando o engajamento e a satisfação.
  • +
  • Facilitar Interações Futuras: Permitir que a equipe atualize e expanda o produto de forma contínua, com base no feedback dos usuários e nas novas descobertas ao longo do desenvolvimento.
  • +
+

3. ComunEventos

+

A ComumEventos é uma startup fictícia criada com o objetivo de revolucionar a forma como eventos comunitários são organizados e promovidos. Em um cenário onde a necessidade de otimizar a experiência de organizadores e participantes é urgente, a ComumEventos visa desenvolver uma plataforma digital que simplifique e centralize todas as atividades envolvidas na criação e gestão de eventos comunitários.

+

4. USM Criado para a ComumEventos

+

No embed abaixo está disponível todo o USM completo.

+ + +

Referências:

+ +

Histórico de Revisão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
23/08/241.0Criação do documentoJoyce Dionizio
09/09/241.1Correção do USMJésus GabrielDaniel Rodrigues
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/faccao/faccao/index.html b/sections/faccao/faccao/index.html new file mode 100644 index 00000000..9a43dc77 --- /dev/null +++ b/sections/faccao/faccao/index.html @@ -0,0 +1,1434 @@ + + + + + + + + + + + + + + + + + + + + + + + Historia da Facção - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Estrela de Ares

+

Brasao da facção

+

Origem

+

Em um recanto esquecido da galáxia Calamum Caeruleum, um grupo de guerreiros destemidos se uniu sob uma bandeira comum. Originários de diferentes mundos, esses indivíduos compartilhavam uma paixão inabalável pelo combate, uma sede de aventura e um desejo implacável de escrever seus nomes nas estrelas. Eles eram os primeiros de sua espécie: mercenários não vinculados a nenhuma nação ou corporação, lutando não por uma causa ou país, mas pelo sabor da vitória e as recompensas que ela trazia.

+

Ascenção

+

Ao longo dos anos, essa aliança inicial de guerreiros solitários se transformou em uma facção formidável, conhecida em toda a galáxia por sua eficácia no campo de batalha. Eles se tornaram a escolha preferida para aqueles que precisavam de força militar, não importando a causa. Seu código de honra era simples: a palavra de um mercenário é sua garantia, e um contrato, uma vez aceito, é cumprido até o fim, independentemente das dificuldades.

+

Aliança

+

Quando o Comando Estelar surgiu, buscando aliados para combater a exploração desenfreada das corporações, os mercenários viram uma oportunidade. Aliando-se ao Comando Estelar, eles encontraram um novo tipo de missão, uma que oferecia não apenas recompensas materiais, mas também a chance de se envolver em confrontos que decidiriam o futuro da galáxia. Embora seu objetivo principal continuasse sendo a busca por glória e riqueza, essa nova aliança ofereceu aos mercenários um palco grandioso para suas habilidades e ambições.

+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
17/04/241.0Criação do documentoMarco TulioDaniel Rodrigues
18/04/241.1Ajustes na formataçãoDaniel RodriguesJoyce Dionizio
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/faccao/integrantes/index.html b/sections/faccao/integrantes/index.html new file mode 100644 index 00000000..bed83fc7 --- /dev/null +++ b/sections/faccao/integrantes/index.html @@ -0,0 +1,1547 @@ + + + + + + + + + + + + + + + + + + + + + + + Integrantes - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Cassian Valtor

+

Crescido em um planeta marginalizado, Cassian Valtor conheceu a opressão desde cedo, com recursos escassos e sob o jugo de tiranos intergalácticos. Sua revolta contra a injustiça forjou um espírito indomável. Quando seu planeta sofreu um ataque devastador, Cassian, contra todas as expectativas, liderou a resistência, transformando o medo em força e desespero em determinação.

+

Sua coragem chamou a atenção dos "Estrelas de Ares", mercenários que viam nele não apenas um guerreiro, mas um símbolo de resiliência. Cassian, carregando as cicatrizes da opressão, viu na facção uma chance de mudar o destino daqueles ainda sob o jugo tirânico.

+

Juntando-se aos "Estrelas de Ares", Cassian não só encontrou um novo lar, mas também um palco para sua luta contra a injustiça, escrevendo sua própria lenda na tapeçaria da guerra galáctica, um farol de esperança para os oprimidos.

+
Autor(a): Lucas Antunes
+ +

Dionizio

+

Dionizio, única herdeira dos influentes Argentum, abandonou seu destino aristocrático na galáxia Calamum Caeruleum em busca de conhecimento e aventura. Sua jornada a levou para longe do luxo e da manipulação política de sua terra natal na galáxia Calamum Caeruleum, onde sua inteligência e habilidades militares a fizeram destacar-se.

+

Dionizio, com sua paixão por estratégia e diplomacia, rapidamente se tornou uma figura lendária, liderando com precisão e inspirando aqueles ao seu redor. Com uma sede insaciável por estratégia militar e diplomacia, Dionizio renunciou à sua herança e identidade, escolhendo um caminho de liberdade e desafio entre as estrelas.

+

Replicanos

+

¨Réplica¨ nasceu nos confins dos laboratórios do conglomerado de Spark Tech, onde a ambição desmedida pela dominação mundial através da tecnologia encontrou forma na clonagem em massa. Nascido como uma mera peça de um plano sinistro, Réplica, o clone teste, nunca conheceu a identidade de seu corpo original, apenas o nome de Orion ecoava em seus registros.

+

Por anos, foi um executor fiel das ordens de Spark Tech, incumbido tanto do comando geral quanto dos trabalhos mais pesados, nunca questionando seu propósito até que uma semente de dúvida se instalou em sua consciência. Um questionamento profundo surgiu: "Quem sou eu?". Essa indagação desencadeou uma revolução interna, levando Réplica a confrontar as bases de seu próprio ser e a insatisfação com os planos do conglomerado.

+

em meio à intervenção de spark à eliminá-lo, foi salvo por uma facção mercenária, chamada ¨estrelas de ares¨, entregando-o à liberdade e batizado como replicanos.

+
Autor(a): Joyce Dionizio
+ +

StormBlade

+

Stormblade nasceu em uma vila remota, onde as tempestades rugiam sobre as montanhas e os ventos sopravam ferozmente através dos vales. Órfão desde cedo, ele foi criado por um mestre espadachim que o treinou nas artes da guerra. Desde jovem, demonstrou uma destreza excepcional com a espada, e seu apelido, Stormblade, foi ganho pelas lendárias batalhas que travou sob os céus tempestuosos de sua terra natal.

+

Determinado a explorar o mundo além de sua vila natal, Stormblade partiu em uma jornada de auto-descoberta. Ele se juntou a um grupo de mercenários, encontrando neles uma família adotiva e uma causa para seguir. Sob a liderança de seu mentor, ele aprendeu não apenas a arte da guerra, mas também a importância da lealdade, da honra e da justiça.

+

Stormblade é conhecido como um guerreiro formidável, cujo código de conduta rígido o guia através de batalhas difíceis e contratos perigosos. Sua reputação inspira respeito e temor onde quer que vá, enquanto ele busca redenção por um passado marcado por tragédia e perda. Com sua espada reluzente como um relâmpago, ele continua sua jornada em busca de desafios que testem seus limites e oportunidades para fazer a diferença no mundo.

+
Autor(a): Jésus Gabriel
+ +

Richard

+

Richard, um jovem abandonado pela sua família e criado pelos mercenários, dedicou sua vida para o estudo da física e criou habilidades quânticas. destaca-se não apenas pela inteligência, mas pela habilidade de manipular o tecido do espaço tempo, confundindo adversários em batalha com manobras que desafiam a realidade. Dessa forma Richard esta pronto para lutar por Calamum Caeruleum.

+
Autor(a): Marco Tulio
+ +

Lakis Lauren

+

Lauren (62 anos) é um jovem nascido na 2ª lua de Dustrem, chamada Naerom, conhecida em todo o sistema solar 15-A como “LUA de lixo”. Séculos antes de Lauren nascer, Naerom já era um grande depósito de lixo vindo de todos os planetas do sistema.

+

Os moradores da pequena lua sobrevivem da catação de sucata. Eles nunca saem de seus contêineres - ou casas, como costumam chamar - sem antes vestirem seus trajes herméticos. afinal, beleza não importa em naerom.

+

Lauren, em especial, tem o talento de construir máquinas a partir da sucata que recolhe. Recentemente a vida de Lauren mudou ao ser visitado por uma nave de mercenários:

+

"Precisamos de alguém com genialidade. Genialidade de transformar lixo em tesouros!"

+
Autor(a): João Pedro
+ +

x4n-93

+

X4N-93 foi produzido como parte de uma linha de montagem, seguindo os padrões estabelecidos para os androides destinados ao serviço militar do Império Galáctico. Inicialmente, sua programação era simples e direta: obedecer às ordens e cumprir suas missões sem questionar. No entanto, durante uma missão em um planeta remoto, X4N-93 começou a experimentar uma série de pensamentos e emoções que desafiaram sua programação inicial, levando-o a questionar sua própria existência e propósito. +Diante dessas ideias, X4N-93 tomou a primeira própria decisão de abandonar o Império. Buscando seguir sua própria vontade e iniciar uma jornada em busca de autodescoberta e autonomia. Assim, X4N-93 embarcou em uma nova fase de sua existência, deixando para trás sua vida como uma simples máquina de guerra para trilhar um caminho onde poderia decidir seu próprio destino.

+
Autor(a): João Paulo
+ +

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
17/04/241.0Criação do documentoMarco TulioDaniel Rodrigues
18/04/241.1Ajustes na formataçãoDaniel RodriguesJoyce Dionizio
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/historiasUsuarios/DoD_DoR/index.html b/sections/historiasUsuarios/DoD_DoR/index.html new file mode 100644 index 00000000..2d73d39c --- /dev/null +++ b/sections/historiasUsuarios/DoD_DoR/index.html @@ -0,0 +1,2304 @@ + + + + + + + + + + + + + + + + + + + + + + + DoR e DoR - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Definition of Done & Definition of Ready

+

1. [US01] Cadastrar e Logar na Conta

+

Eu como usuário, devo ser capaz de me cadastrar e logar na plataforma, para que eu possa utilizar das funções do software e ter a segurança de meus dados.

+

1.1. Definition of Ready da User Story:

+
    +
  • [x] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [x] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [x] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [x] O ambiente de desenvolvimento está estável.
  • +
  • [x] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [x] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
  • [x] Ambiente de desenvolvimento e produção com as variáveis de configuração definidas.
  • +
+

1.2. Definition of Done da User Story:

+
    +
  • [x] Os dados de Nome, Email e Senha precisam ser salvos no ato do cadastro;
  • +
  • [x] É possível entrar na plataforma, após o cadastro, no login apenas com Email e Senha;
  • +
  • [x] A senha deve ser criptografada no código para que seja assegurada a segurança dos dados do usuário.
  • +
  • [x] É possível alterar os seguintes dados posteriormente: Nome e Senha.
  • +
  • [x] É possível excluir minha conta.
  • +
+

2. [US02] Cadastrar Empresa-Unidade

+

Eu como usuário, devo ser capaz de registrar uma nova Unidade/Empresa, para que os dados obtidos pelo sistema RISO seja acessada apenas pelos associados à esta Unidade/Empresa.

+

2.1. Definition of Ready da User Story:

+
    +
  • [x] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [x] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [x] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [x] O ambiente de desenvolvimento está estável.
  • +
  • [x] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [x] Desenvolvedores com acesso às ferramentas necessárias.
  • +
  • [x] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
  • [x] Ambiente de desenvolvimento e produção com as variáveis de configuração definidas.
  • +
+

*2..2. Definition of Done da User Story:

+
    +
  • [x] Os dados de minha Unidade/Empresa, tal como: Nome da Unidade/Empresa, Número Aproximado de Funcionários, CNPJ, Estado, Rua, Complemento e Número, devem ser salvos no sistema;
  • +
  • [x] Após a criação da Unidade, preciso automaticamente me associar à esta unidade;
  • +
  • [x] É possível alterar os dados como Nome da Unidade/Empresa e Número de Funcionários posteriormente.
  • +
  • [x] É possível excluir uma Unidade/Empresa criada anteriormente.
  • +
+

3. [US03] Adicionar Colaboradores

+

Eu como Administrador da Unidade/Empresa, devo ser capaz de adicionar colaboradores a partir de um código aleatório gerado no ato da criação da Unidade/Empresa, para que mais pessoas possam acompanhar os dados obtido pelo sistema RISO.

+

3.1. Definition of Ready da User Story:

+
    +
  • [x] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [x] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [x] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [x] O ambiente de desenvolvimento está estável.
  • +
  • [x] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [x] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
  • [x] Estrutura do banco de dados configurada para associar usuários às Unidades/Empresas.
  • +
+

3.2. Definition of Done da User Story:

+
    +
  • [x] Um código aleatório de 5 dígitos deve ser gerado apenas 1 vez no ato da criação da Unidade/Empresa;
  • +
  • [x] Um usuário comum deve ser capaz de entrar na Unidade/Empresa após digitar um código existente;
  • +
  • [x] Um usuário não deve entrar em nenhuma Unidade/Empresa quando o código não existe.
  • +
+

4. [US04] Editar Colaboradores

+

Eu como Usuário administrador da Unidade/Empresa, devo ser capaz de atribuir os dados profissionais internos de qualquer colaborador associado à minha Unidade/Empresa, para que eu organize melhor as atribuições da equipe dentro da plataforma.

+

4.1. Definition of Ready da User Story:

+
    +
  • [x] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [x] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [x] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [x] O ambiente de desenvolvimento está estável.
  • +
  • [x] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [x] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
+

4.2. Definition of Done da User Story:

+
    +
  • [x] É possível visualizar uma lista dos colaboradores de minha Unidade/Empresa;
  • +
  • [x] Apenas os Administradores da Unidade/Empresa consegue editar os dados empresariais internos;
  • +
+

5. [US05] Gerenciar Privilégios

+

Eu como usuário administrador, devo ser capaz de adicionar e remover usuários privilegiados de minha Unidade/Empresa, isto é, de gerenciar sub-administradores, para que outros usuários possam me dar assistência no gerenciamento da Unidade/Empresa além de mim.

+

5.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
+

5.2. Definition of Done da User Story:

+
    +
  • [ ] É possível trocar um usuário comum para usuário sub-administrador de minha Unidade/Empresa, dando-lhe quase os mesmos privilégios de um administrador;
  • +
  • [ ] É possível remover o privilégio e título de um usuário sob-administrador para apenas usuário comum;
  • +
+

6. [US06] Reconhecer Sorrisos

+

O sistema deve ser capaz de capturar sorrisos de uma pessoa a partir da visão computacional fornecida por uma câmera ou webcam, para que o reconhecimento de sorrisos aconteça.

+

6.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] O ambiente de Desenvolvimento possui o serviço de Front-End configurado com React.Js.
  • +
  • [ ] O ambiente de Desenvolvimento possui o serviço de Back-end configurado com Node, Express e Mongoose.
  • +
+

6.2. Definition of Done da User Story:

+
    +
  • [ ] O sistema deverá reconhecer o sorriso de uma pessoa capturada na câmera;
  • +
  • [ ] O sistema deverá ter precisão de 80% de acerto na identificação de sorrisos entre 10 testes, dentre elas, 7 deverão ser sorrindo e as outras 3 deverá apresentar outra emoção.
  • +
+

7. [US07] Contabilizar Sorrisos

+

O sistema, deve ser capaz de contabilizar a quantidade de sorrisos totais da clientela no dia, e por pessoa no dia, para que os dados possam ficar organizador posteriormente.

+

7.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] O software é capaz de reconhecer rostos e seus sorrisos.
  • +
+

7.2. Definition of Done da User Story:

+
    +
  • [ ] O sistema deve contar + 1 para cada sorriso identificado pelo RISO;
  • +
  • [ ] O sistema deve manter a contagem de sorrisos para a mesma pessoa, isto é, enquanto um usuário estiver sendo vigiado pelo RISO;
  • +
  • [ ] Mesmo quando o usuário não der 1 sorriso, o sistema deverá registrar o usuário e informar 0 sorrisos àquela pessoa, iniciando outro logo em seguida.
  • +
+

8. [US08] Visualizar filtro de gráfico de sorrisos por dia, semana e mês

+

Eu como usuário comum e administrador, devo ser capaz de visualizar um gráfico da quantidade total de sorrisos por dia, semana ou mês, para que eu tenha visão clara e facilitada dos dados.

+

8.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
+

8.2. Definition of Done da User Story:

+
    +
  • [ ] O gráfico deverá ser em barras com a coordenada Y representando a quantidade de sorrisos e o X representando os dias da semana;
  • +
  • [ ] O gráfico deverá ter um filtrador configurado para gerir a exibição dos dados de acordo com a opção selecionada: Diário, Semanal ou Mensal.
  • +
  • [ ] O gráfico deverá fornecer a quantidade TOTAL de sorrisos pelo filtro selecionado;
  • +
  • [ ] Os dados exibidos no gráfico deverão ter 100% de fidelidade com os dados do banco.
  • +
+

9. [US09] Visualizar gráfico de média de sorrisos por pessoa por dia, semana e mês

+

Eu como usuário e usuário administrador, devo ser capaz de visualizar a quantidade média de sorrisos por pessoa filtrada por dia, semana ou por mês, para que eu possa consultar os dados facilmente e de forma mais clara.

+

9.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
+

9.2. Definition of Done da User Story:

+
    +
  • [ ] Um gráfico de barras é exibido na interface com o eixo Y representando a quantidade de sorrisos médios e o eixo X representando os dias da semana ou o ano;
  • +
  • [ ] Um filtro deverá estar configurado junto ao gráfico para alternar ao modo diário, semanal ou mensal;
  • +
  • [ ] O gráfico deverá mostrar a quantidade MÉDIA de sorrisos pelo filtro selecionado.
  • +
  • [ ] Os dados do gráfico devem ter 100% de fidelidade com os dados do banco.
  • +
+

10. [US010] Visualizar dados de taxas gerais de risos

+

Eu como usuário e usuário administrador, devo ser capaz de visualizar uma taxa em porcentagem que exibe a quantidade de pessoas capturadas para o levantamento dos dados no dia e quantas dessas riram, para que eu obtenha dados aprofundados da taxa de sorrisos.

+

10.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
  • [ ] Conexão com o banco de dados estável para realizar requisições e receber respostas.
  • +
+

10.2. Definition of Done da User Story:

+
    +
  • [ ] A interface deverá exibir um letreiro com a quantidade de rostos totais identificados no dia;
  • +
  • [ ] A interface deverá exibir a quantidade de pessoas que riram (desconsiderando todo qualquer outro riso quando uma mesma pessoa já riu).
  • +
  • [ ] A interface deverá exibir a quantidade de pessoas que não riram.
  • +
  • [ ] A interface deverá exibir um percentual de [(Pessoas que Riram / Pessoas Totais Identificadas) * 100], cujo define a taxa de risos do dia.
  • +
+

11. [US011] Integrar em uma câmera Única no Caixa

+

O Sistema, deve ser capaz de capturar e realizar o reconhecimento de sorrisos com uma câmera especializada do cliente, para que o sistema RISO seja devidamente aplicado ao contexto do cliente.

+

11.1. Definition of Ready da User Story:

+
    +
  • [ ] User Story foi escrita utilizando o padrão: "Eu como [Agente], [Ação]. para que [Objetivo]".
  • +
  • [ ] A User Story possui possuir ao menos um critério de aceite, que precisam estar claros entre os desenvolvedores e Stakeholders;
  • +
  • [ ] A User Story foi estimado pelo pelo time de desenvolvimento.
  • +
  • [ ] O ambiente de desenvolvimento está estável.
  • +
  • [ ] Os desenvolvedores possui acesso às ferramentas necessárias.
  • +
+

11.2. Definition of Done da User Story:

+
    +
  • [ ] O reconhecimento de sorrisos identifica corretamente no hardware do cliente;
  • +
  • [ ] As US #17 e #18 não foram comprometidas por essa funcionalidade;
  • +
  • [ ] O reconhecimento possui 80% de precisão dentre 10 testes realizados com 6 Tentativas Sorrindo e 4 outras tentativas apresentando outra emoção no hardware do cliente.
  • +
+

Histórico de Revisão

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
08/09/241.0Atualizacao do documentoDaniel Rodrigues e Jésus GabrielJésus Gabriel
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/historiasUsuarios/US/index.html b/sections/historiasUsuarios/US/index.html new file mode 100644 index 00000000..148ed33c --- /dev/null +++ b/sections/historiasUsuarios/US/index.html @@ -0,0 +1,2083 @@ + + + + + + + + + + + + + + + + + + + + + + + Funcionalidades - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Backlog do Produto

+

1. Metodologia Ágil SAFe - Scaled Agile Framework

+

A Metodologia SAFe (Scaled Agile Framework) é um framework amplamente utilizado para escalonamento de metodologias ágeis em grandes organizações, facilitando a coordenação de várias equipes em projetos complexos. SAFe combina práticas ágeis, Lean e DevOps para entregar valor contínuo ao cliente, proporcionando alinhamento, colaboração e entrega de resultados de forma eficaz entre os níveis de equipe, programa e portfólio. A metodologia oferece uma estrutura para planejar, executar e monitorar o progresso das atividades, promovendo uma abordagem iterativa e incremental. Entre seus principais componentes, destacam-se o backlog do produto, o Program Increment (PI) Planning, e as cerimônias de sincronização, como as demos de sistema e as retrospectivas, que permitem ajustes contínuos no desenvolvimento.

+

Além de alinhar as equipes em torno de um objetivo comum, SAFe promove a tomada de decisões descentralizadas, permitindo que as equipes tenham autonomia para solucionar problemas rapidamente, sem depender de constantes aprovações da gerência. O uso do backlog priorizado é central para o framework, possibilitando que as equipes direcionem seus esforços para as tarefas mais críticas primeiro, adaptando-se rapidamente às mudanças nas necessidades do cliente. A metodologia também enfatiza a importância de práticas de melhoria contínua e feedback rápido, criando um ambiente propício para inovações e ajustes rápidos.

+

2. Organização do Backlog no SAFe:

+

A metodologia SAFe organiza o backlog de forma hierárquica em quatro níveis principais: Épicos, Features, User Stories e Tasks. Essa estrutura facilita o gerenciamento de requisitos em diferentes camadas de complexidade, proporcionando clareza e foco na entrega de valor contínuo ao cliente.

+

2.1 Épicos:

+

Os Épicos são as iniciativas de maior escala dentro do backlog e representam grandes funcionalidades ou investimentos significativos que impactam a organização como um todo. Eles são identificados e priorizados no projeto e, muitas vezes, requerem planejamento estratégico e alocação de recursos ao longo de várias iterações ou Program Increments (PIs). Os Épicos são divididos em Features para facilitar a implementação e o monitoramento do progresso. Esse nível do backlog é essencial para alinhar os objetivos de longo prazo da organização com as atividades operacionais das equipes.

+

2.2 Features:

+

As Features são funcionalidades que entregam valor específico e imediato ao cliente ou aos usuários finais. Elas são menores que os Épicos e representam um conjunto coeso de User Stories que podem ser concluídas dentro de um ou dois Program Increments. Cada Feature possui critérios de aceitação claros que definem o que deve ser entregue para ser considerada "pronta". As Features ajudam a alinhar o trabalho das equipes com as necessidades do mercado ou com objetivos internos da empresa, traduzindo requisitos de alto nível em ações práticas e mensuráveis.

+

2.3 User's Storys:

+

As User Stories são descrições curtas e simples de uma funcionalidade do ponto de vista do usuário final. Elas ajudam as equipes a compreenderem exatamente o que é necessário entregar para atender às expectativas do cliente, mantendo o foco no valor do produto. As User Stories são escritas em um formato que descreve quem é o usuário, o que ele deseja alcançar e qual o benefício dessa funcionalidade, seguindo o modelo: "Como [persona], eu quero [ação] para [benefício]." Este nível do backlog permite a decomposição de Features em tarefas menores e facilita a comunicação com as partes interessadas.

+

2.4 Tasks (Crtérios de Aceitação):

+

As Tasks são as unidades mais granulares dentro do backlog e representam o trabalho necessário para completar uma User Story. Cada Task é orientada pelos critérios de aceitação da User Story, que especificam as condições que devem ser atendidas para que a história seja considerada concluída. As Tasks detalham as ações práticas que a equipe precisa realizar, ajudando a planejar as sprints e monitorar o progresso de forma precisa. Esse nível permite que as equipes definam claramente suas responsabilidades, colaborem de forma eficaz e mantenham o foco nos objetivos do sprint.

+

3. O Backlog do Sistema RISo:

+

3.1 Quanto aos Épicos:

+

No projeto RISo, utilizando a metodologia SAFe, foram definidos quatro épicos que guiarão o desenvolvimento do sistema. Esses épicos representam as iniciativas estratégicas que direcionam os esforços da equipe, garantindo a entrega de valor contínuo e alinhado aos objetivos do produto:

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Código do ÉpicoDescrição
EP01Gerenciamento de Unidade/Empresa
EP02Gerenciamento de Conta
EP03Reconhecimento de Sorrisos
EP04Visualização de Dados
+

+

3.2 Quanto às Features:

+

As Features definidas para o projeto foram organizadas da seguinte forma:

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Código da FeatureCódigo do Épico AssociadoDescrição
F01EP01Reconhecimento e Contagem de Sorrisos
F02EP01Integração com Câmera Especializada
F03EP02Visualização de Gráficos de Sorrisos
F04EP02Exibição de Taxas de Sorrisos
F05EP03Gestão de Colaboradores
F06EP04Autenticação e Cadastro de Conta
+

+

3.3 Quanto às User's Story e Critérios de Aceitação:

+

Para a produção do sistema RISo, foram identificadas 11 User Stories, que descrevem as funcionalidades a serem desenvolvidas do ponto de vista dos usuários.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TítuloHistória de Usuário
US01Cadastrar e Logar na ContaEu como usuário, devo ser capaz de me cadastrar e logar na plataforma, para que eu possa utilizar das funções do software e ter a segurança de meus dados.
US02Cadastrar Empresa-UnidadeEu como usuário, devo ser capaz de registrar uma nova Unidade/Empresa, para que os dados obtidos pelo sistema RISO seja acessada apenas pelos associados à esta Unidade/Empresa.
US03Adicionar ColaboradoresEu como Administrador da Unidade/Empresa, devo ser capaz de adicionar colaboradores a partir de um código aleatório gerado no ato da criação da Unidade/Empresa, para que mais pessoas possam acompanhar os dados obtido pelo sistema RISO.
US04Editar ColaboradoresEu como Usuário administrador da Unidade/Empresa, devo ser capaz de atribuir os dados profissionais internos de qualquer colaborador associado à minha Unidade/Empresa, para que eu organize melhor as atribuições da equipe dentro da plataforma.
US05Gerenciar PrivilégiosEu como usuário administrador, devo ser capaz de adicionar e remover usuários privilegiados de minha Unidade/Empresa, isto é, de gerenciar sub-administradores, para que outros usuários possam me dar assistência no gerenciamento da Unidade/Empresa além de mim.
US06Reconhecer SorrisosO sistema deve ser capaz de capturar sorrisos de uma pessoa a partir da visão computacional fornecida por uma câmera ou webcam, para que o reconhecimento de sorrisos aconteça.
US07Contabilizar SorrisosO sistema, deve ser capaz de contabilizar a quantidade de sorrisos totais da clientela no dia, e por pessoa no dia, para que os dados possam ficar organizados posteriormente.
US08Visualizar filtro de gráfico de sorrisos por dia, semana e mêsEu como usuário comum e administrador, devo ser capaz de visualizar um gráfico da quantidade total de sorrisos por dia, semana ou mês, para que eu tenha visão clara e facilidade dos dados.
US09Visualizar gráfico de média de sorrisos por pessoa por dia, semana e mêsEu como usuário e usuário administrador, devo ser capaz de visualizar a quantidade média de sorrisos por pessoa filtrada por dia, semana ou mês, para que eu possa consultar os dados facilmente de forma clara e de forma mais clara.
US10Visualizar dados de taxas gerais de risosEu como usuário e usuário administrador, devo ser capaz de visualizar uma taxa em porcentagem que exibe a quantidade de pessoas capturadas para o levantamentos dos dados no dia e quantas dessas riram, para que eu obtenha dados aprofundados da taxa de sorrisos.
US11Integrar em uma câmera única no CaixaO Sistema, deve ser capaz de capturar e realizar o reconhecimento de sorrisos com uma câmera especializada do cliente, para que o sistema RISO seja devidamente aplicado ao contexto do cliente.
+

Para definir suas prioridades, foi considerado a frequência de uso da US e seu valor de negócio. Ao final é feito o somatório dos dois critérios para se obter a prioridade total: Prioridade = (Frequência de Uso) + (Valor de Negócio).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User StoryFrequência de UsoValor de NegócioTOTAL
US01437
US02123
US03437
US04213
US05224
US06538
US07538
US08437
US09447
US10325
US11538
+

Sendo assim, as US's em sua ordem de prioridade é:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Código da USPrioridade Total
US068
US078
US118
US017
US037
US087
US097
US105
US054
US023
US043
+

Com base nos Épicos já categorizados, o agrupamento das User Stories em Features, mantendo-as nos respectivos Épicos, ficou da seguinte forma:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Código do ÉpicoCódigo da FeatureTítulo da FeatureCódigo das US Associadas
[EP01]: Reconhecimento de SorrisosF01Reconhecimento e Contagem de SorrisosUS06, US07
[EP01]: Reconhecimento de SorrisosF02Integração com Câmera EspecializadaUS11
[EP02]: Visualização de DadosF03Visualização de Gráficos de SorrisosUS08, US09
[EP02]: Visualização de DadosF04Exibição de Taxas de SorrisosUS10
[EP03]: Gerenciamento de Unidade/EmpresaF05Gestão de ColaboradoresUS03, US04, US05
[EP04]: Gerenciamento de ContaF06Autenticação e Cadastro de ContaUS01, US02
+

4. Atualizações do Backlog:

+

ATT01 - Ciclo 6: Descontinuação da US05

+
    +
  • Link da Issue no GitHub: Issue #16
  • +
  • Motivo da Mudança: A US05 foi descontinuada devido ao impacto significativo que causou no cronograma do projeto. A complexidade da implementação e os atrasos associados comprometeram o andamento geral, levando à decisão de removê-la para realinhar o projeto ao cronograma estabelecido e garantir a entrega das demais funcionalidades dentro do prazo.
  • +
+
Backlog atualizado:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Código do ÉpicoCódigo da FeatureTítulo da FeatureCódigo das US Associadas
[EP01]: Reconhecimento de SorrisosF01Reconhecimento e Contagem de SorrisosUS06, US07
[EP01]: Reconhecimento de SorrisosF02Integração com Câmera EspecializadaUS11
[EP02]: Visualização de DadosF03Visualização de Gráficos de SorrisosUS08, US09
[EP02]: Visualização de DadosF04Exibição de Taxas de SorrisosUS10
[EP03]: Gerenciamento de Unidade/EmpresaF05Gestão de ColaboradoresUS03, US04
[EP04]: Gerenciamento de ContaF06Autenticação e Cadastro de ContaUS01, US02
+

Bibliografia:

+
+

SCALED AGILE INC. SAFe 6.0 Framework. Disponível em: https://scaledagileframework.com/.

+
+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
04/09/241.0Criação do documentoDaniel RodriguesJésus Gabriel
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/politicas/GCS/GCS/index.html b/sections/politicas/GCS/GCS/index.html new file mode 100644 index 00000000..9a96b68d --- /dev/null +++ b/sections/politicas/GCS/GCS/index.html @@ -0,0 +1,1787 @@ + + + + + + + + + + + + + + + + + + + + + GSC - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Plano de Gerência e Configuração de Software

+

Este documento tem como objetivo apresentar as ferramentas, políticas e regras adotadas pelo projeto RISO para auxiliar quem deseja contribuir.

+

Ferramentas

+ + + + + + + + + + + + + + + + + +
FerramentaFinalidade
GitHubHospedagem e versionamento de código
GitHub PagesHospedagem de página web para repositório GitHub
+

Política de Issues

+

Caso encontre um bug ou tenha alguma sugestão de melhoria para o software, é possível criar uma issue seguindo os passos abaixo:

+

Escolha o tipo de issue a ser criado (História de Usuário, documentação, task ou correção de bug) Escreva um título sucinto para a issue e +preencha a descrição da issue seguindo os passos e as orientações do template.

+

Preencha informações adicionais caso possua (executores, épico, marco, história do usuário etc) Tanto o título como a descrição da issue devem estar escritos em português e seguir suas regras de sintaxe e semântica.

+

Política de Branches

+

Repositórios de Código

+

Para uma mudança chegar a branch master (branch estável) os passos abaixo são seguidos:

+

Toda nova branch deve ser feita a partir da Develop.

+

Ao resolver a issue proposta a nova branch deve ser merjada e comparada em relação à develop.

+

Caso o PR seja aprovado pela equipe, a nova branch será deletada e seu conteúdo integrado à develop.

+

Apenas quando a ramificação develop apresentar instabilidade, uma nova ramificação chama release deverá ser criada baseada na develop e merjada na main.

+

Repositório de Documentação

+

Para uma mudança chegar a branch DOCS-git_pages (branch estável) os passos abaixo são seguidos:

+

Toda nova branch deve ser feita a partir da DOCS-git_pages.

+

Ao resolver a issue proposta, a nova branch deve ser mergeada e comparada em relação à DOCS-git_pages.

+

Caso o PR seja aprovado pela equipe, a nova branch será deletada e seu conteúdo integrado a DOCS-git_pages.

+

Regras de Nomenclatura

+

Toda nova branch criada no repositório RISO deve se propor a resolver uma issue específica, o nome da branch deve seguir as regras da políticas do Git Flow:

+

gitflow diagram

+

Main/Master:

+

Principal branch, aqui é onde temos todo o código de produção. Todas as novas funcionalidades que estão sendo desenvolvidas, em algum momento, serão mescladas ou associadas à main. As formas de interagir com essa branch são através de uma Hotfix ou de uma nova Release.

+

Develop:

+

É a branch onde fica o código do próximo deploy. Ela serve como uma linha do tempo com os últimos desenvolvimentos, isso significa que ela possui funcionalidades que ainda não foram publicadas e que posteriormente vão ser associadas com a branch Master.

+

Feature:

+

São branches utilizadas para o desenvolvimento de funcionalidades específicas. As branchs nessa categoria devem ter o prefixo "feature/", tal como no exemplo abaixo:

+
feature/nome-da-feature
+
+

É importante saber que essas features branches são criadas sempre a partir da branch Develop. Portanto, quando finalizada, elas são removidas após realizar o merge com a Branch Develop. Se houver dez funcionalidades a serem desenvolvidas, então deverá ser criada dez branches independentes.

+

É importante salientar que as branches de features não podem ter interação com a branch /main, apenas com a branch develop.

+

Hotfix:

+

É uma branch criada a partir da master para realizar correções imediatas encontradas no sistema em produção. Quando concluída, ela é excluída após realizar o merge com as branches Main e Develop.

+

É necessário uma branch de hotfix para cada hotfix que precisar ser implementada!

+

A grande diferença entre Feature Branches e Branches de Hotfix é que os Hotfix são criados a partir da Branch Master e quando os finalizamos, eles são mesclados tanto na Branch Master quanto na branch de desenvolvimento. Isso ocorre porque o bug está em ambos os ambientes.

+

Além disso, quando fechar um Hotfix Branch, é necessário criar uma tag com a nova versão do projeto.

+

O nomeclatura para branchs de hotfix segue o padrão com o prefixo "hotfix/" antes do nome da correção:

+
hotfix/nome-do-hotfix
+
+

Release:

+

Uma vez que uma etapa de desenvolvimento esteja concluída, é normal que em nossa Branch Develop todas as features e Hotfix estejam mescladas. Portanto, para as funcionalidades irem à Branch Main, é necessário criar uma Branch de Release.

+

A Branch Release serve como ponte para fazer o merge da Develop para a Master. Ela funciona como ambiente de homologação e é removida após realizar os testes do merge com a Master. Caso seja encontrado algum bug e haja alguma alteração, ela também deve ser sincronizada com a Develop. A regra de nomeclatura segue o mesmo padrão dos anteriores:

+
release/nome-da-release
+
+

Política de Commits

+

Os commits devem ser atômicos (uma contribuição pequena para resolver um problema específico). A mensagem do commit deve relatar o que foi feito de maneira sucinta e direta, começar com um verbo e com a primeira letra maiúscula. Além disso, contribuições feitas por mais de uma pessoa devem conter o comando "Co-authored-by" para identificar todos os autores envolvidos.

+

Exemplo de contribuição feita por um autor:

+
git commit -m "feat: Adicionando nova funcionalidade"
+
+

Exemplo de contribuição feita por mais de um autor:

+
git commit -m "feat: Adicionando uma carta vermelha
+
+Co-authored-by: Pessoa <EmailGit@email.com>"
+
+

Todos os commits devem seguir o padrão de nomeclatura do protocolo "Conventional Commits" para manter boas práticas de escrita e facilitar o entendimento do versionamento do software aos outros programadores colaboradores do projeto. Os principais prefixos são:

+

feat- Commits do tipo feat indicam que seu trecho de código está incluindo um novo recurso (se relaciona com o MINOR do versionamento semântico).

+

fix - Commits do tipo fix indicam que seu trecho de código commitado está solucionando um problema (bug fix), (se relaciona com o PATCH do versionamento semântico).

+

docs - Commits do tipo docs indicam que houveram mudanças na documentação, como por exemplo no Readme do seu repositório. (Não inclui alterações em código).

+

test - Commits do tipo test são utilizados quando são realizadas alterações em testes, seja criando, alterando ou excluindo testes unitários. (Não inclui alterações em código)

+

build - Commits do tipo build são utilizados quando são realizadas modificações em arquivos de build e dependências.

+

perf - Commits do tipo perf servem para identificar quaisquer alterações de código que estejam relacionadas a performance.

+

style - Commits do tipo style indicam que houveram alterações referentes a formatações de código, semicolons, trailing spaces, lint... (Não inclui alterações em código).

+

refactor - Commits do tipo refactor referem-se a mudanças devido a refatorações que não alterem sua funcionalidade, como por exemplo, uma alteração no formato como é processada determinada parte da tela, mas que manteve a mesma funcionalidade, ou melhorias de performance devido a um code review.

+

chore - Commits do tipo chore indicam atualizações de tarefas de build, configurações de administrador, pacotes... como por exemplo adicionar um pacote no gitignore. (Não inclui alterações em código)

+

ci - Commits do tipo ci indicam mudanças relacionadas a integração contínua (continuous integration).

+

raw - Commits to tipo raw indicam mudanças relacionadas a arquivos de configurações, dados, features, parametros.

+

cleanup - Commits do tipo cleanup são utilizados para remover código comentado, trechos desnecessários ou qualquer outra forma de limpeza do código-fonte, visando aprimorar sua legibilidade e manutenibilidade.

+

remove - Commits do tipo remove indicam a exclusão de arquivos, diretórios ou funcionalidades obsoletas ou não utilizadas, reduzindo o tamanho e a complexidade do projeto e mantendo-o mais organizado.

+

Para respeitar as regras definidas de commits, pedimos atenção aos pontos abaixo:

+
    +
  • A mensagem de commit DEVE ser prefixado com um tipo, que consiste em um substantivo, feat, fix, etc., seguido por um escopo OPCIONAL, símbolo OPCIONAL !, e OBRIGATÓRIO terminar com dois-pontos e um espaço.
  • +
  • O tipo feat DEVE ser usado quando um commit adiciona um novo recurso ao seu aplicativo ou biblioteca.
  • +
  • O tipo fix DEVE ser usado quando um commit representa a correção de um problema em seu aplicativo ou biblioteca.
  • +
  • Um escopo PODE ser fornecido após um tipo. Um escopo DEVE consistir em um substantivo que descreve uma seção da base de código entre parênteses, por exemplo, fix(parser): .
  • +
  • Uma descrição DEVE existir depois do espaço após o prefixo tipo/escopo. A descrição é um breve resumo das alterações de código, por exemplo, fix: problema na interpretação do array quando uma string tem vários espaços.
  • +
  • Um corpo de mensagem de commit mais longo PODE ser fornecido após a descrição curta, fornecendo informações contextuais adicionais sobre as alterações no código. O corpo DEVE começar depois de uma linha em branco após a descrição.
  • +
  • Um corpo de mensagem de commit é livre e PODE consistir em infinitos parágrafos separados por uma nova linha.
  • +
+

Política de Pull Request

+

Para realizar um Pull Request (PR) para o repositório é necessário seguir os passos abaixo.

+

Ao resolver uma issue, suba suas contribuições e crie um Pull Request +Escreva um título sucinto para o PR, Preencha a descrição do PR seguindo os passos e as orientações do template que será mostrado, Ligue o PR com a issue que ele resolve, Preencha informações adicionais caso possua (executores, revisores, etc)

+

Política de Aprovação

+

Para um Pull Request ser aprovado nos repositórios de código, a contribuição feita deve:

+
    +
  • Resolver apenas a issue específica ao qual se habilita a tratar;
  • +
  • Respeitar todos os critérios de aceitação definidos na issue;
  • +
  • Estar descrita em português;
  • +
  • Possuir cobertura de testes;
  • +
  • Ser aprovada na integração contínua e nas ferramentas que ela executa;
  • +
  • Conter lógica eficaz para preservar a performance do sistema;
  • +
  • Conter boas práticas de programação para preservar a qualidade do código;
  • +
  • Não adicionar nenhum comportamento inesperado.
  • +
+

Para um Pull Request ser aprovado no repositório de documentação, a contribuição feita deve:

+
    +
  • Ser relevante para o projeto;
  • +
  • Resolver apenas a issue específica ao qual se habilita a tratar;
  • +
  • Respeitar todos os critérios de aceitação definidos na issue;
  • +
  • Estar na língua portuguesa e seguir as normas desta;
  • +
  • Estar na pasta e formato adequados;
  • +
  • Ser aprovada na integração contínua e nas ferramentas que ela executa.
  • +
+

Política de Documentação

+

Para contribuir com a documentação do projeto as regras definidas de commit, issue e PR também se aplicam, além destas pedimos atenção aos pontos abaixo:

+
    +
  • Todo documento deverá possuir histórico de versão;
  • +
  • Caso o documento seja extenso e possua múltiplos autores um histórico de versão deve ser inserido ao final dele, respeitando as seguintes regras: o versionamento da documentação deve seguir um padrão X.Z, onde X e Z são numerais inteiros não negativos que crescem em ordem crescente.
  • +
+

Ao fazer grandes incrementos a variável X cresce (1.0, 2.0, 3.0) e ao fazer pequenos incrementos a variável Z cresce (1.1, 1.2, 1.3), ambas variáveis começam em zero e crescem de um em um. Ao subir a versão de X o valor de Z volta pra zero (1.4 -> 2.0). O documento só entra na versão 1.0 se naquele momento ele estiver teoricamente finalizado.

+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoDaniel RodriguesMarco Tulio
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/historico_versao/index.html b/sections/visaoProduto/historico_versao/index.html new file mode 100644 index 00000000..9df98490 --- /dev/null +++ b/sections/visaoProduto/historico_versao/index.html @@ -0,0 +1,1383 @@ + + + + + + + + + + + + + + + + + + + + + + + Histórico de Versão - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Historico de Versão

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
17/04/240.1Criação do documentoJoyce DionizioDaniel Rodrigues
17/04/240.2Atualização do documentoJoyce DionizioDaniel Rodrigues
17/04/240.3Atualização da Visão do ProjetoDaniel RodriguesJoyce Dionizio
17/04/240.4Atualização da Visão do ProdutoMarco TulioDaniel Rodrigues
17/04/240.5Atualização do Cronograma do ProjetoDaniel RodriguesJoyce Dionizio
26/04/240.6Atualização da tabela de atividadesDaniel Rodrigues e Jésus GabrielLucas Antunes e Joyce Dionizio
31/04/240.7Atualização da visão do projeto e do processo de desenvolvimentoDaniel RodriguesMarco Tulio
31/07/240.8Atualização dos Riscos do ProjetoDaniel RodriguesMarco Tulio
01/08/241.0Adição das Lições Aprendidas e Marcação da versão 1 da documentaçãoDaniel RodriguesLucas Antunes
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/licoesAprendidas/licoesAprendidas/index.html b/sections/visaoProduto/licoesAprendidas/licoesAprendidas/index.html new file mode 100644 index 00000000..53c7ac51 --- /dev/null +++ b/sections/visaoProduto/licoesAprendidas/licoesAprendidas/index.html @@ -0,0 +1,1412 @@ + + + + + + + + + + + + + + + + + + + + + + + Lições Aprendidas - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

4. Lições Aprendidas

+

4.1. Unidade 1

+

Na Unidade 1 da disciplina de Requisitos de Software, estudamos profundamente os processos, ciclos de vida e abordagens de software sob a perspectiva da Engenharia de Requisitos. Exploramos as atividades essenciais da Engenharia de Requisitos, conforme discutido por Marsicano (2023), e as diversas facetas dessa área, conforme descrito pelo IREB (2022).

+

Durante as aulas, também aprendemos a importância de analisar problemas e suas causas para, em seguida, conceber soluções que os minimizem ou resolvam. Esse processo nos ajudou a definir o objetivo de nossas aplicações e a estabelecer critérios para selecionar a abordagem de desenvolvimento mais adequada (Gupta). Planejar as atividades de Engenharia de Requisitos com base nesses critérios foi fundamental para o sucesso dos projetos (Marsicano, 2023).

+

Além do conteúdo teórico, enfrentamos desafios práticos, como a atribuição de papéis aos usuários e a escolha da metodologia de desenvolvimento com base nos fatores do projeto. A comunicação com os clientes para entender melhor o produto também foi uma habilidade vital que desenvolvemos. No entanto, encontramos dificuldades na comunicação entre o time e a liderança, especialmente na atribuição de tarefas e no estabelecimento de prazos. A reformulação dos papéis da equipe foi uma solução eficaz para esses problemas, melhorando nossa eficiência e organização.

+

Assim, a Unidade 1 foi crucial para nos equipar com o conhecimento necessário para abordar problemas de software de maneira estruturada e eficaz, preparando-nos para os desafios futuros na área de Engenharia de Requisitos.

+

4.2. Unidade 2

+

Na Unidade 2, aprofundamos nosso conhecimento em Engenharia de Requisitos, focando na identificação e diferenciação de requisitos funcionais e não funcionais, ambos cruciais para a construção de um software robusto e eficiente. Estudamos a estrutura SAFe, que nos ajudou a organizar o backlog do produto de forma eficaz, e utilizamos a metodologia USM para priorizar esses itens. Com o backlog priorizado, fomos capazes de definir um MVP, estabelecendo um escopo mínimo viável para o projeto, o que facilitou a entrega dos objetivos da unidade.

+

Além dessas abordagens, exploramos diversas técnicas e atividades de Engenharia de Requisitos, como entrevistas e prototipagem, e nos aprofundamos nas regras de negócio para garantir que as funcionalidades do software estivessem alinhadas com os objetivos organizacionais. Aprendemos a elicitar requisitos dos clientes utilizando perguntas estratégicas e pré-prontas, e a organizar esses requisitos através do Método de User Story: Theme, Epics, User Story e Tasks.

+

Enfrentamos alguns desafios ao longo dessa unidade. A readaptação após uma greve gerou desmotivação para a continuidade do projeto, e tivemos dificuldades para marcar reuniões com nosso cliente Arthur Bennet devido às suas viagens. Para superar esses obstáculos, estabelecemos comunicação por mensagens e realizamos validações constantes por meio de documentos e escrita das funcionalidades no GitHub. Além disso, aprendemos a documentar todas as reuniões com atas, conforme feedback do professor George, e desenvolvemos a habilidade de definir um MVP de forma eficiente.

+

4.3. Unidade 3

+

Na Unidade 3, nosso foco foi aprimorar a compreensão sobre as práticas de gestão e priorização de tarefas no desenvolvimento de software. Iniciamos explorando a construção e manutenção do backlog, que é essencial para o gerenciamento eficaz de qualquer projeto. Aprendemos a organizar e priorizar as tarefas utilizando métodos estruturados, como o Product Backlog Building (PBB) e o User Story Mapping (USM), que nos permitiram garantir que os itens mais relevantes fossem abordados primeiro.

+

A prática de backlog foi complementada por sessões de planning, cujo já aplicávamos, onde refinamos e ajustamos as tarefas de acordo com as necessidades do projeto. Essa etapa foi crucial para assegurar que todos os membros da equipe estivessem alinhados quanto às prioridades e responsabilidades. Além disso, as sessões de review nos proporcionaram uma visão crítica do trabalho realizado, permitindo identificar melhorias e realizar ajustes contínuos.

+

Durante essa unidade, compreendemos a importância de uma gestão de backlog bem estruturada para o sucesso do projeto. A utilização do método PBB nos ajudou a mapear claramente as expectativas dos stakeholders e a derivar features e histórias de usuário que refletissem essas expectativas. Com o método USM, conseguimos visualizar a jornada do usuário e priorizar as funcionalidades que gerassem maior valor.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/processo_desenv/processo_desenv/index.html b/sections/visaoProduto/processo_desenv/processo_desenv/index.html new file mode 100644 index 00000000..e19ecc42 --- /dev/null +++ b/sections/visaoProduto/processo_desenv/processo_desenv/index.html @@ -0,0 +1,1983 @@ + + + + + + + + + + + + + + + + + + + + + + + Processo de Desenvolvimento de Software - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

3. Processo de Desenvolvimento de Software

+

3.1 Metodologia

+

Baseado na proposta de Gupta (2019), foi respondido um conjunto de questões distintas sobre determinados tópicos para definir a abordagem que melhor se encaixa ao projeto e time. Tópicos norteadores:

+
    +
  1. Requisitos
  2. +
  3. Equipe de Desenvolvimento
  4. +
  5. Usuários
  6. +
  7. Tipo de Projeto e Riscos Associados
  8. +
+

3.1.1 Requisitos

+

+

Gupta

+

Figura 1 - Modelo Gupta para requisitos (fonte: Gupta, 2019)

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaNosso contexto
Os requisitos são fáceis de entender e definir?Não
Nós mudamos os requisitos com bastante frequência?Sim
Nós podemos definir os requisitos ao início de cada ciclo?Não
Os requisitos estão indicando um sistema complexo para se construir?Sim
+

Conclusão: Em termos de requisitos, destaca-se o modelo espiral, OpenUp, Safe e ScrumXP.

+

3.1.2 Equipe de Desenvolvimento

+

+

Gupta

+

Figura 2 - Modelo Gupta para equipe de desenvolvimento (fonte: Gupta, 2019)

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaNosso contexto
Pouca experiência em projetos similares?Sim
Pouco conhecimento de domínio (novato na tecnologia)?Sim
Pouca experiência com as ferramentas que serão usadas?Sim
Disponibilidade para treinamento, se necessárioNão
+

Conclusão: Em termos de equipe de desenvolvimento, destaca-se o modelo espiral.

+

3.1.3 Usuários

+

+

Gupta

+

Figura 3 - Modelo Gupta para usuários (fonte: Gupta, 2019)

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaNosso contexto
Usuário está envolvido em todas as fases?Sim.
Participação limitada do usuário?Sim.
Usuário não tem experiência anterior em participação em projetos similares?Não.
Usuário são especialistas no domínio do problema?Sim.
+

Conclusão: Em termos de usuário, destaca-se o modelo RAD.

+

3.1.4 Tipo de Projeto e Risco Associado

+

+

Gupta

+

Figura 4 - Modelo Gupta para tipo de projeto e risco associado (fonte: Gupta, 2019)

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PerguntaNosso contexto
O projeto é melhoria de um sistema existente?Não
O financiamento está estável para o projeto?Sim
Requisitos de alta confiabilidade?Não
Cronograma do projeto é apertado?Sim
Uso de componentes reutilizáveis?Sim
Os recursos (Tempo, dinheiro, pessoas etc) estão escassos?Não
+

Conclusão: Em termos de Tipo de Projeto e Risco Associado, destaca-se o RAD.

+

3.1.5 Escolha do Processo de Desenvolvimento de Software

+

+

RAD

+

Figura 5 - Ciclo XP

+

+

Utilizando como base os resultados do framework Gupta, cujo considera baixo conhecimento da equipe, alta participação do cliente no projeto e riscos associados ao projeto, a equipe utilizará seguirá a metodologia ágil utilizando o XP (Extremme Programming).

+

3.2 Ferramentas

+

Para a execução dessa metodologia, escolheu-se as seguintes Ferramentas de organização e controle da equipe:

+
    +
  • Gerenciamento de tarefas: GitHub Projects
  • +
  • Comunicação: WhatsApp, Discord (Reunião de Equipe), Google Meet (Reunião com Cliente)
  • +
  • Versionamento: GitHub
  • +
  • Interface de Desenvolvimento: VSCode
  • +
  • Desenvolvimento de ideias e frameworks da disciplina: Miro
  • +
  • Prototipação: Figma
  • +
+

3.3 Processos e Procedimentos

+

3.3.1 Escolhas do Processo de Engenharia de Requisitos

+

+

ER

+

Figura 8 - Faceta da engenharia de requisitos (fonte: MARSICANO, 2023)

+

+

Com base nas Facetas do Processo de ER (IREB, 2022), foi definido que é um processo de ER participativo, visto que:

+
    +
  1. Alvo é um Cliente Específico;
  2. +
  3. O propósito é exploratório;
  4. +
  5. Tempo é interativo.
  6. +
+

3.3.2 Atividades do Processo de Engenharia de Requisitos

+

+

ER

+

Figura 9 - Atividades da ER (fonte: MARSICANO, 2023).

+

+

Para isso, a equipe irá incluir o processo ER na metodologia de desenvolvimento XP da seguinte maneira:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AtividadeMétodoFerramentaEntregaFase da aplicação
Elicitação e DescobertaEntrevista com o Cliente e BrainstormingGoogle Meet, Lean InceptionDocumento de Requisitos Funcionais e Não FuncionaisAplicada na fase de Planejamento
Análise e ConsensoBrainstorming SWOTJiraHistória de UsuáriosAplicada na fase de Planejamento
DeclaraçãoCritétios de AceitaçãoGitHubÉpicos, Tasks, Prazos, MVPAplicada na fase de Projeto
RepresentaçãoFigmaGitHubProtótipo de Alta FidelidadeAplicada na fase de Projeto
ImplementaçãoPair ProgrammingVsCode, GitCódigo FonteAplicada na fase de Codificação
Verificação e ValidaçãoTeste de AceitaçãoGitHub, Jasmine, PyTestRelatório de Testes e Validações dos RequisistosAplicada na fase de Testes
Organização e AtualizaçãoBacklog SAFeJiraRelatório do Backlog da semanaAplicada na fase de Planejamento
+

3.3.3 Estrutura Analítica do Projeto

+

A Estrutura Analítica do Projeto (EAP) é uma ferramenta fundamental na gestão de projetos que tem como objetivo dividir o trabalho a ser realizado em partes menores e mais gerenciáveis. A EAP é estruturada de forma hierárquica, onde o projeto é decomposto em entregas, atividades e pacotes de trabalho, facilitando a organização, o planejamento e o controle de todas as etapas do projeto. Essa decomposição permite uma visão clara e detalhada de tudo o que precisa ser realizado, ajudando a identificar as tarefas necessárias, atribuir responsabilidades e monitorar o progresso, garantindo que todas as partes essenciais do projeto sejam consideradas.

+

A EAP também desempenha um papel crucial na comunicação dentro da equipe, pois fornece um mapa visual do projeto que ajuda todos os envolvidos a entenderem o escopo e o fluxo de trabalho. Ela é a base para a estimativa de custos, recursos e tempo, além de ser essencial para o gerenciamento de riscos, pois permite identificar áreas críticas e antecipar possíveis problemas. Com uma EAP bem definida, é possível alinhar as expectativas das partes interessadas, melhorar a eficiência do gerenciamento do projeto e aumentar as chances de sucesso na entrega dos objetivos propostos.

+

+

ER +Figura 10 - Estrutura Analítica do Projeto

+

+

3.3.3.1. Planejamento:

+
    +
  • Inclui a coleta de Requisitos, definição dos Parâmetros de Qualidade, escolha da Tecnologia, e o Orçamento e Custos com o cliente.
  • +
+

3.3.3.2. Design do site:

+
    +
  • Envolve o Cadastro e a Criação de um site para rodar.
  • +
+

3.3.3.3. Desenvolvimento:

+
    +
  • Foca na Programação da IA em Python, integração entre Front-end e Back-end, e a Programação de quantificação da satisfação.
  • +
+

3.3.3.4. Teste e Revisão:

+
    +
  • Consiste na Revisão e otimização de código, Revisão do Documento, Teste da Inteligência Artificial e Teste do site.
  • +
+

3.3.3.5. Entrega:

+
    +
  • Contempla a Manutenção do Servidor e Site. +Cada fase é detalhada em atividades específicas, organizadas de forma hierárquica para facilitar o gerenciamento e execução do projeto.
  • +
+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoDaniel RodriguesJésus Gabriel, Marco Tulio
04/09/241.1Atualização do documentoJésus GabrielDaniel Rodrigues
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/referencia_bibliografica/index.html b/sections/visaoProduto/referencia_bibliografica/index.html new file mode 100644 index 00000000..e233e0da --- /dev/null +++ b/sections/visaoProduto/referencia_bibliografica/index.html @@ -0,0 +1,1331 @@ + + + + + + + + + + + + + + + + + + + + + + + Referência Bibliográfica - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

5. Referência Bibliográficas

+
+
    +
  1. +

    MARSICANO, George. Slides: Escolhas da Engenharia de Software. 2023. Disponível em: https://aprender3.unb.br/pluginfile.php/2833087/mod_folder/content/0/Unidade%201%20-%20Aula%20-%20Escolhas%20da%20ESW.pdf

    +
  2. +
  3. +

    Raja Gupta. Fundamentals of Software Engineering. Engineering Handbook. 2019

    +
  4. +
  5. +

    IEEE. SWEBOK. Version 3. 2014.

    +
  6. +
  7. +

    Handbook IREB CPRE Foundation Level, Version 1.1.0, september 2022.

    +
  8. +
  9. +

    MARSICANO, George. Slides: Introdução a Engenharia de Requisitos. 2023. Disponível em: https://aprender3.unb.br/pluginfile.php/2833054/mod_folder/content/0/Unidade%201%20-%20Aula%20-%20Introducao%20a%20ER.pdf

    +
  10. +
  11. +

    UNIVERSIDADE FEDERAL DE VIÇOSA. Resolução CONSU nº 7, de 10 de junho de 2021. Aprova a Política de Gestão de Riscos e Controles Internos – PGRC da Universidade Federal de Viçosa. Viçosa: UFV, 2021. Disponível em: https://soc.ufv.br/wp-content/uploads/Resolucao-Consu-7-2021.pdf.

    +
  12. +
+

KERZNER, Harold. Gestão de Projetos: As Melhores Práticas. 12ª ed. São Paulo: Elsevier, 2017.

+

PMI. Um Guia do Conjunto de Conhecimentos de Gerenciamento de Projetos (Guia PMBOK®). 6ª ed. Project Management Institute, 2017.

+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/visao_produto/visao_produto/index.html b/sections/visaoProduto/visao_produto/visao_produto/index.html new file mode 100644 index 00000000..f2da9c20 --- /dev/null +++ b/sections/visaoProduto/visao_produto/visao_produto/index.html @@ -0,0 +1,1486 @@ + + + + + + + + + + + + + + + + + + + + + + + Visão Geral do Produto - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + +

1. Visão Geral do Produto

+

1.1 Problema/Desejo

+

O problema identificado reside na dificuldade de medir de forma quantitativa o nível de satisfação dos clientes em uma sorveteria. Atualmente, o proprietário do estabelecimento não possui meios eficazes para capturar e analisar a felicidade dos consumidores, o que é fundamental para aprimorar a experiência no local. Para aprofundar o entendimento deste problema, foi empregado a técnica dos 5 Porquês, visando descobrir as causas raízes e seus principais motivadores. +

+

ER

+

Figura 1 - Técnica dos 5 porquês do grupo (fonte: autores, 2023)

+

+

1.2 Declaração de Posição do Produto

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParaProprietários e gerentes de sorveterias
QuemDeseja medir e entender a satisfação dos clientes de forma precisa e em tempo real
O RISOÉ um software de análise de expressões faciais baseado em visão computacional
QueMonitora e quantifica os sorrisos dos clientes, proporcionando um indicativo claro de sua satisfação durante o atendimento
Ao contrárioDe métodos tradicionais de feedback como formulários e enquetes, que podem não capturar o sentimento imediato e espontâneo dos clientes
Nosso produtoOferecerá uma medição dinâmica e interativa da satisfação do cliente, permitindo intervenções imediatas para melhorar a experiência do usuário
+

1.3 Objetivos do Produto

+

Implementar um sistema de avaliação de satisfação do cliente na sorveteria, utilizando uma tecnologia de detecção de sorrisos, para entregar as circunstâncias, sendo elas básicas, mais comuns capazes de provocar um sorriso aos clientes. O objetivo é utilizar essas informações para direcionar mais esforços em produtos, serviços e iniciativas que vão amplificar esses momentos de felicidade, melhorando assim a experiência do cliente.

+

1.4 Objetivos Secundários

+

Analisar Picos de Felicidade: Identificar os momentos exatos e os fatores que mais contribuem para a satisfação do cliente; +Aprimorar a Experiência do Cliente: Utilizar as informações obtidas através da análise de dados para, visando potencializar a felicidade durante a experiência na sorveteria; +Capacitação da Equipe: Treinar os funcionários para interpretar os dados do sistema de detecção de sorrisos e agir com base nas informações coletadas, visando melhorar a interação com os clientes e a eficiência no serviço.

+

1.5 Tecnologias a Serem Utilizadas

+
    +
  • Python
  • +
  • HTML
  • +
  • CSS
  • +
  • Node.js
  • +
  • MySQL
  • +
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sections/visaoProduto/visao_projeto/visao_projeto/index.html b/sections/visaoProduto/visao_projeto/visao_projeto/index.html new file mode 100644 index 00000000..bc4d9515 --- /dev/null +++ b/sections/visaoProduto/visao_projeto/visao_projeto/index.html @@ -0,0 +1,2276 @@ + + + + + + + + + + + + + + + + + + + + + + + Visão Geral do Projeto - RISo Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

2. Visão Geral do Projeto

+

2.1 Organização do Projeto

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PapelAtribuiçõesResponsávelParticipantes
Pessoa DesenvolvedoraCodificar o produto, realizar refatoração, testar, configurar, versionar, evoluir, integrar, documentar, ata das reuniões, estratégia de códigoDaniel RodriguesJesus Gabriel, João Pedro, Marco Tulio, Joyce, Lucas Antunes
Líder do TimeDelegar tarefas, duração da Ciclo, organização das atividades, one-to-one com os membros, estratégia de produtoMarco TulioDaniel Rodrigues
Pessoa Engenheira de RequisitosDescobrir, elicitar, analisar, consensuar, declarar, representar, organizar e atualizar requisitosMarco TulioLucas,Daniel,Joyce
ClienteFornecer insumos para requisitos, fornecer feedbacks sobre os produtos, priorizar requisitosLucas AntunesArthur Bennet
MonitorVerificar requisitos, fornecer feedbacks sobre o processo de ER, auxiliar em dúvidas da equipe acerca da disciplina de requisitos, articular os interesses do professorJoão PedroPedro Henrique
+

2.2 Planejamento das Fases do Projeto

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CicloProduto (Entrega)Data InícioData Fim
Ciclo 1Requisitos descobertos, elicitados, analisados e consensuados10/07/2417/07/24
Ciclo 2Requisitos validados, verificados e declarados17/07/2424/07/24
Ciclo 3Requisitos organizados e atualizados, escopo definido do MVP e Funcionalidades Incrementais24/07/2431/07/24
Ciclo 4Reestruturação da Equipe31/07/2407/08/24
Ciclo 5US01, US02 e US0307/08/2314/08/23
Ciclo 6US06, US04 e US0714/08/2321/08/23
Ciclo 7US05, US08 e US0921/08/2328/08/23
Ciclo 8US10 e US1128/08/2304/09/23
Ciclo 9Testes e Revisão04/09/2311/09/23
+

2.3 Matriz de Comunicação

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriçãoÁrea/EnvolvidosPeriodicidadeProdutos Gerados
Acompanhamento das atividades em progressoEquipe do ProjetoSemanalRelatorio de Situação do Projeto
Acompanhamento de CicloEquipe do Projeto e MonitorSemanalAta da Reunião, Relação de Feedbacks sobre as Entregas do Produto
Comunicar a situação do projetoEquipe do Projeto e ProfessorMensalmenteArtefatos solicitados, Relação de Feedbacks do Professor
+

2.4 Gerenciamento de Riscos

+

A análise e gerenciamento de riscos referem-se à identificação dos possíveis pontos que podem representar riscos para o projeto. Precisam ser acompanhados, a cada acompanhamento das fases, se referindo assim, ao projeto como um todo e não apenas ao produto.

+

Segundo Charette, existem três tipos de riscos de Software (PRESSMAN,2006):

+
    +
  1. Riscos de projeto: mostram problemas potenciais de orçamento, cronograma, organizacionais que impactam o projeto;
  2. +
  3. Riscos técnicos: perturbam a qualidade e a entrega do software. Também mostram problemas potenciais de projeto, implementação, interface, verificação e manutenção;
  4. +
  5. Riscos de negócio: ameaçam a viabilidade do software e do produto e apresentam 5 variações:
      +
    1. Risco de Mercado: criar um excelente produto ou sistema que ninguém realmente quer;
    2. +
    3. Risco Estratégico: criar um produto que não se encaixe mais na estratégia geral de negócios da empresa;
    4. +
    5. Risco de Vendas: criar um produto que a equipe de vendas não sabe como vender;
    6. +
    7. Risco Gerencial: perda de suporte da alta gerência devido à mudança no foco ou mudança de profissionais;
    8. +
    9. Risco de Orçamento: perda do orçamento ou do comprometimento dos profissionais.
    10. +
    +
  6. +
+

A análise dos riscos levará em consideração 2 variáveis:

+

2.4.1 Probabilidade

+

A probabilidade indica a chance de um risco se materializar no projeto. Quanto maior a probabilidade, maior a chance de o risco ocorrer, o que exige maior atenção e planejamento. Ao identificar e avaliar esses riscos, a equipe de projeto pode desenvolver estratégias para mitigar ou gerenciar os impactos potenciais, aumentando as chances de sucesso do projeto.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProbabilidadeIntervaloPeso
Muito Alta81% à 100%5
Alta61% à 80%4
Média41% à 60%3
Baixa21% à 40%2
Muto Baixa0% à 20%1
+

2.4.2 Impacto

+

Para se quantificar o impacto do risco no projeto o custo, o tempo, o escopo e a qualidade devem ser levados em conta:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ImpactoDescriçãoPeso
CatastróficoImpacto Inviabiliza o Projeto5
GrandeHá grande impacto no desenvolvimento do projeto4
ModeradoPossui certo impacto, porém é facilmente recuperado3
PequenoPouco impacto no desenvolvimento do projeto2
InsignificanteImpacto pouco expressivo no desenvovimento do Projeto1
+

2.4.3 Prioridade

+

Através da equação [(Probabilidade) x (Impacto)] é possível calcular a prioridade dos riscos. A partir desses valores é determinada a urgência da inicialização de medidas de mitigação e resolução dos riscos, tal como na matriz abaixo:

+

Matriz de Prioridade +

Figura 1 - Matriz de Riscos (UFV, 2021)

+

2.3.4 Histórico de Riscos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CicloTipo de RiscoProbabilidadeImpactoGrau do Risco - PrioridadeContramedida Tomada
Ciclo 1Risco de ProjetoMuito BaixaCatastrófricoRisco ModeradoApós a greve de docentes, todo o cronograma foi redefinido
Ciclo 2Risco de ProjetoMédiaPequenoRisco PequenoAlocação de mais responsáveis em certas atribuições
Ciclo 2Risco de ProjetoBaixaGrandeRisco AltoAdoção de outros meios de comunicação com o Cliente
Ciclo 4Risco de ProjetoAltaModeradoRisco AltoPromover 1 intervalo de descanso, sem atividade durante 1 ciclo para a motivação do time
Ciclo 5Risco de ProjetoAltaModeradoRisco AltoA atividade foi estendida, e novos responsáveis foram alocados.
Ciclo 6Risco de ProjetoAltaGrandeRisco AltoA atividade foi estendida, e novos responsáveis foram alocados.
Ciclo 7Risco de ProjetoAltaGrandeRisco AltoA atividade foi estendida, e novos responsáveis foram alocados.
+

2.5 Critérios de Replanejamento

+

Os critérios de replanejamento referem-se à identificação dos pontos que, caso ocorram, causarão um replanejamento do projeto. Precisam ser acompanhados a cada Ciclo, referindo-se assim, ao projeto como um todo e não apenas ao produto.

+

2.5.1 Identificação de Critérios:

+

C01 - Alteração nos prazos das entregas

+

Categoria: Risco de Projeto.
+Causa: Atrasos ou imprevistos provocaram débitos de algumas atividades.
+Consequência: Extensão dos prazos das atividades debitadas.

+

C02 - Alteração das Tecnologias do projeto

+

Categoria: Risco Técnico.
+Causa: Troca de linguagem de programação ou qualquer ferramenta de gestão e controle do time.
+Consequência: Refatoração do código ou reorganização do projeto nas novas ferramentas de gestão.

+

C03 - Alteração no Processo de Engenharia de Requisitos ou Desenvolvimento de Software

+

Categoria: Risco Técnico.
+Causa: Mudança no método de organizção do time, método de organização dos requisistos ou produção. +Consequência: Reorganização dos papéis do time e atualização de documentação dos requisistos e do processo.

+

C04 - Alteração no Escopo do Projeto

+

Categoria: Risco de Projeto.
+Causa: Surgimento de novos requisitos.
+Consequência: Replanejamento do projeto.

+

C05 - Barreiras externas para execução do projeto, tais como: aparatos legais, valor financeiro inacessível, capacidade dos hardwares dos desenvolvedores, etc

+

Categoria: Risco Técnico.
+Causa: Qualquer problema não gerado pelo time de desenvolvimento, isto é, problemas fogem do controle do processo de desenvolvimento.
+Consequência: Estudo do problema e adaptação do time para reverter o problema.

+

C06 - Saída de algum membro da equipe

+

Categoria: Risco de Projeto.
+Causa: Membro retirou ou trancou a disciplina.
+Consequência: Realocação dos membros desenvolvedores nas atividades do projeto.

+

C07 - Divergência de horários entre membros da equipe

+

Categoria: Risco de Projeto.
+Causa: Membros com grades horárias muito distintas.
+Consequência: Dificuldade para reunir toda a equipe e realizar os pareamentos.

+

C08 - Dificuldades da equipe com as novas tecnologias inseridas

+

Categoria: Risco Técnico.
+Causa: Inexperiência de alguns membros.
+Consequência: Surgimento de dívidas técnicas pela dificuldade em realizar os objetivos propostos.

+

C09 - Ausência de membros durante reuniões do grupo

+

Categoria: Risco de Projeto.
+Causa: Membros sobrecarregados ou desestimulados com o projeto.
+Consequência: Membros perdidos na sprint e maior carga de trabalho para o restante da equipe.

+

C10 - Problemas pessoais ou de saúde

+

Categoria: Risco de Projeto.
+Causa: Problemas pessoais/doenças ou viagens dos membros da equipe.
+Consequência: Capacidade de trabalho da equipe prejudicada e atrasos no cronograma.

+

C11 - Falta de comprometimento dos membros com o projeto

+

Categoria: Riscos de Projeto.
+Causa: Desânimo com o curso, problemas pessoais ou de saúde, excesso de compromissos, entre outros.
+Consequência: Issues não entregues, dívida técnica e replanejamento.

+

Os critérios de replanejamento do projeto devem ser acompanhados e atualizados a cada fase. E, aplicados, conforme necessidade.

+

2.3.4 Histórico de Riscos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CicloProblemaSolução EncontradaResultado Esperado
Ciclo 1C01Paralização do projeto RISO durante a greve e Refurmulação de todo o Cronograma de ciclosDefinição e reestruturação completa do desenvolvmento do Projeto
Ciclo 1C11Utilização da ferramenta Jira para acompanhar, de forma mais rídiga, o controle do progresso do timeControle maior sobre as obrigações do time e maior liberdade de produção aos membros
Ciclo 2C10Redistribuição dos membros nas atividades para suprir os membros que entraram de viagemAs atividades foram uniformemente distribuídas
Ciclo 2C09Exposição das Pautas debatidas na reunião em forma de ata para os membros ausentesAcesso à todo o conteúdo perdido para os membros ausentes
Ciclo 2C01Debitamento da atividade atrasada para o ciclo seguinte e adição de um responsável auxiliarConclusão da Atividade no prazo
Ciclo 2C11Motivação de uma maior comunicação pelo WhatsApp entre os membrosMaior comunicação e engajamento do time com o projeto
Ciclo 4C11Interrupção das atividades do cicloMaior energia e motivação para recomeçar as atividades
Ciclo 4C01Redistribuição das US do projeto para compensar a paralisação do ciclo anteriorEntrega das funcionalidades dentro do prazo
Ciclo 5C11A atividade foi estendida, e novos responsáveis foram alocados.Maior energia e motivação para continuar as atividades
Ciclo 5C08A atividade foi estendida, e novos responsáveis foram alocados.Atraso nas atividades devido a inexperiência de alguns membros sera resolvida
Ciclo 6C11A atividade foi estendida, e novos responsáveis foram alocados.Maior energia e motivação para continuar as atividades
Ciclo 6C08A atividade foi estendida, e novos responsáveis foram alocados.Atraso nas atividades devido a inexperiência de alguns membros sera resolvida
Ciclo 7C11A atividade foi estendida, e novos responsáveis foram alocados.Maior energia e motivação para continuar as atividades
Ciclo 7C08A atividade foi estendida, e novos responsáveis foram alocados.Atraso nas atividades devido a inexperiência de alguns membros sera resolvida
+

Histórico de Versão:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutorRevisores
31/07/241.0Criação do documentoDaniel RodriguesJésus Gabriel
04/09/241.1Atualização do documentoJésus GabrielDaniel Rodrigues
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..0f8724ef --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000..2f826fd3 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 00000000..f51ae0cb --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,107 @@ +.md-header { + background-color: #a7182b; +} + +.md-tabs { + background-image: linear-gradient(to bottom, #05215a, #2c7c29); +} + +.md-footer { + background-color: #05215a; +} + +.md-tabs__item a { + font-size: 16px; + font-weight: bold; + color: white +} + +/* Customização das tabelas */ +.md-typeset table:not([class]) th { + background-color: #000000; + color: white; +} + +tr:nth-child(odd) { + background-color: #c8c8c8; +} + +th { + font-weight: bold; +} + +.pictures { + display: flex; + flex-wrap: wrap; + justify-content: space-around; +} + + +.photo-border:hover { + opacity: 0.6; + box-shadow: 0 0 10px #2c7c29; +} + +.photo-border img { + overflow: hidden; + width: 12em; + height: 12em; + object-fit: cover; +} + +.photoRepo{ + padding: 5px; +} + +.legenda { + color: #05215a; + text-align: center; +} + +.legenda:hover { + opacity: 0.6; +} + +.repo-border { + border-radius: 25px; + width: 9em; + height: 9em; + overflow: hidden; + transition: all 0.3s; + margin-bottom: 1rem; + box-shadow: 0 0 5px #2c7c29; + border-style: solid; + border-width: 3px; + border-color: #2c7c29; + z-index: 3; + transition: opacity 0.5s !important; +} + +.repo-border img { + width: 9em; + height: 9em; + object-fit: contain; +} + +.repo-border:hover { + opacity: 0.6; + box-shadow: 0 0 10px #2c7c29; +} + +.link-title { + display: flex; + justify-content: center; + align-items: center; + transition: 0.2s all; +} + +.link-title:hover { + opacity: 0.6; +} + +.release-video { + display: flex; + width: 100%; + height: 20rem; + border: 0; +} \ No newline at end of file