diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index aa07e5a841..c639673783 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,67 +1,87 @@ -name: Build and Deploy Docs +# Sample workflow for building and deploying a VitePress site to GitHub Pages +# +name: Deploy VitePress site to Pages + on: + # Runs on pushes targeting the `main` branch. Change this to `master` if you're + # using the `master` branch as the default branch. push: - branches: - - main -jobs: - build-and-deploy: - name: Build and Deploy - runs-on: ubuntu-latest - env: - MIKE_VERSION: v4 - MIKE_ALIAS: stable - DOCKER_IMAGE: ui5-tooling/mkdocs-material - GIT_COMMITTER_NAME: "OpenUI5 Bot" - GIT_COMMITTER_EMAIL: "openui5@sap.com" - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Use Node.js LTS 20.x - uses: actions/setup-node@v4.0.3 - with: - node-version: 20.x + branches: [main] - - name: Install npm dependencies - run: npm ci + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: - - name: Fetch gh-pages branch - run: git fetch origin gh-pages --depth=1 +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: write + pages: write + id-token: write - - name: Set /site ownership to current user - run: | - mkdir site - sudo chown -R $(id -u):$(id -g) ./site +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: pages + cancel-in-progress: false - - name: Build docs with Mike - run: ./scripts/buildDocs.sh - - - name: Publish docs - run: docker run --rm -v $(pwd):/docs --entrypoint mike --env GIT_COMMITTER_NAME="${GIT_COMMITTER_NAME}" --env GIT_COMMITTER_EMAIL="${GIT_COMMITTER_EMAIL}" $DOCKER_IMAGE set-default stable --push - - - name: Build Schema - run: | - npm run schema-generate - npm run schema-workspace-generate - - - name: Checkout gh-pages - uses: actions/checkout@v4 - with: - ref: gh-pages - path: gh-pages - - name: Copy the additional resources to gh-pages - run: | - rm -rf ./gh-pages/schema - cp -R ./site/schema ./gh-pages/ - rm -rf ./gh-pages/$MIKE_VERSION/api - cp -R ./site/api ./gh-pages/$MIKE_VERSION/ - cp ./scripts/resources/custom404.html ./gh-pages/404.html - - name: Publish Docs - run: | - cd ./gh-pages - git config --local user.email $GIT_COMMITTER_EMAIL - git config --local user.name $GIT_COMMITTER_NAME - git add . - git commit -m "Updating supplemental resources for ${MIKE_VERSION} documentation deployment" - git push +jobs: + # Build job + build: + runs-on: ubuntu-latest + env: + DOC_VERSION: v4 + DOC_ALIAS: stable + GIT_COMMITTER_NAME: "Konrad Kost" + GIT_COMMITTER_EMAIL: "xxxx" + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Not needed if lastUpdated is not enabled + # - uses: pnpm/action-setup@v3 # Uncomment this if you're using pnpm + # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm # or pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm i # or pnpm install / yarn install / bun install + - name: Fetch gh-pages branch + run: git fetch origin gh-pages --depth=1 + - name: Set /site ownership to current user + run: | + mkdir site + sudo chown -R $(id -u):$(id -g) ./site + - name: generate CLI doc + run: npm run generate-cli-doc # or pnpm install / yarn install / bun install + - name: Build jsdoc + run: npm run jsdoc-generate + - name: Build vitepress build + run: npm run docs:build + - name: Build Schema + run: | + npm run schema-generate + npm run schema-workspace-generate + - name: Checkout gh-pages + uses: actions/checkout@v4 + with: + ref: gh-pages + path: gh-pages + - name: Copy the additional resources to gh-pages + run: | + rm -rf ./gh-pages/schema + cp -R ./site/schema ./gh-pages/ + rm -rf ./gh-pages/$DOC_VERSION + cp -R ./site ./gh-pages/$DOC_VERSION/ + cp ./scripts/resources/custom404.html ./gh-pages/404.html + - name: Publish Docs + run: | + cd ./gh-pages + git config --local user.email $GIT_COMMITTER_EMAIL + git config --local user.name $GIT_COMMITTER_NAME + git add . + git commit -m "Updating supplemental resources for ${DOC_VERSION} documentation deployment" + git push diff --git a/.gitignore b/.gitignore index 1f157785d0..403a839112 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ site/ # Custom files docs/pages/CLI.md +docs/CLI.md + diff --git a/.vitepress/cache/deps/_metadata.json b/.vitepress/cache/deps/_metadata.json new file mode 100644 index 0000000000..90c89a0180 --- /dev/null +++ b/.vitepress/cache/deps/_metadata.json @@ -0,0 +1,52 @@ +{ + "hash": "b6be9fd8", + "configHash": "f384ce4c", + "lockfileHash": "23ddd169", + "browserHash": "a06b72e2", + "optimized": { + "vue": { + "src": "../../../node_modules/vue/dist/vue.runtime.esm-bundler.js", + "file": "vue.js", + "fileHash": "ceacbf15", + "needsInterop": false + }, + "vitepress > @vue/devtools-api": { + "src": "../../../node_modules/@vue/devtools-api/dist/index.js", + "file": "vitepress___@vue_devtools-api.js", + "fileHash": "eafcbfdc", + "needsInterop": false + }, + "vitepress > @vueuse/core": { + "src": "../../../node_modules/@vueuse/core/index.mjs", + "file": "vitepress___@vueuse_core.js", + "fileHash": "b61e56d9", + "needsInterop": false + }, + "vitepress > @vueuse/integrations/useFocusTrap": { + "src": "../../../node_modules/@vueuse/integrations/useFocusTrap.mjs", + "file": "vitepress___@vueuse_integrations_useFocusTrap.js", + "fileHash": "1482b0ac", + "needsInterop": false + }, + "vitepress > mark.js/src/vanilla.js": { + "src": "../../../node_modules/mark.js/src/vanilla.js", + "file": "vitepress___mark__js_src_vanilla__js.js", + "fileHash": "b7b81973", + "needsInterop": false + }, + "vitepress > minisearch": { + "src": "../../../node_modules/minisearch/dist/es/index.js", + "file": "vitepress___minisearch.js", + "fileHash": "fd23aab4", + "needsInterop": false + } + }, + "chunks": { + "chunk-YVCV7MZG": { + "file": "chunk-YVCV7MZG.js" + }, + "chunk-45KCXATN": { + "file": "chunk-45KCXATN.js" + } + } +} \ No newline at end of file diff --git a/.vitepress/cache/deps/chunk-45KCXATN.js b/.vitepress/cache/deps/chunk-45KCXATN.js new file mode 100644 index 0000000000..dcaf4f28e8 --- /dev/null +++ b/.vitepress/cache/deps/chunk-45KCXATN.js @@ -0,0 +1,11482 @@ +// node_modules/@vue/shared/dist/shared.esm-bundler.js +function makeMap(str, expectsLowerCase) { + const set2 = new Set(str.split(",")); + return expectsLowerCase ? (val) => set2.has(val.toLowerCase()) : (val) => set2.has(val); +} +var EMPTY_OBJ = true ? Object.freeze({}) : {}; +var EMPTY_ARR = true ? Object.freeze([]) : []; +var NOOP = () => { +}; +var NO = () => false; +var isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter +(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97); +var isModelListener = (key) => key.startsWith("onUpdate:"); +var extend = Object.assign; +var remove = (arr, el) => { + const i = arr.indexOf(el); + if (i > -1) { + arr.splice(i, 1); + } +}; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var hasOwn = (val, key) => hasOwnProperty.call(val, key); +var isArray = Array.isArray; +var isMap = (val) => toTypeString(val) === "[object Map]"; +var isSet = (val) => toTypeString(val) === "[object Set]"; +var isDate = (val) => toTypeString(val) === "[object Date]"; +var isRegExp = (val) => toTypeString(val) === "[object RegExp]"; +var isFunction = (val) => typeof val === "function"; +var isString = (val) => typeof val === "string"; +var isSymbol = (val) => typeof val === "symbol"; +var isObject = (val) => val !== null && typeof val === "object"; +var isPromise = (val) => { + return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch); +}; +var objectToString = Object.prototype.toString; +var toTypeString = (value) => objectToString.call(value); +var toRawType = (value) => { + return toTypeString(value).slice(8, -1); +}; +var isPlainObject = (val) => toTypeString(val) === "[object Object]"; +var isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; +var isReservedProp = makeMap( + // the leading comma is intentional so empty string "" is also included + ",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted" +); +var isBuiltInDirective = makeMap( + "bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo" +); +var cacheStringFunction = (fn) => { + const cache = /* @__PURE__ */ Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +}; +var camelizeRE = /-(\w)/g; +var camelize = cacheStringFunction((str) => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : ""); +}); +var hyphenateRE = /\B([A-Z])/g; +var hyphenate = cacheStringFunction( + (str) => str.replace(hyphenateRE, "-$1").toLowerCase() +); +var capitalize = cacheStringFunction((str) => { + return str.charAt(0).toUpperCase() + str.slice(1); +}); +var toHandlerKey = cacheStringFunction((str) => { + const s = str ? `on${capitalize(str)}` : ``; + return s; +}); +var hasChanged = (value, oldValue) => !Object.is(value, oldValue); +var invokeArrayFns = (fns, ...arg) => { + for (let i = 0; i < fns.length; i++) { + fns[i](...arg); + } +}; +var def = (obj, key, value, writable = false) => { + Object.defineProperty(obj, key, { + configurable: true, + enumerable: false, + writable, + value + }); +}; +var looseToNumber = (val) => { + const n = parseFloat(val); + return isNaN(n) ? val : n; +}; +var toNumber = (val) => { + const n = isString(val) ? Number(val) : NaN; + return isNaN(n) ? val : n; +}; +var _globalThis; +var getGlobalThis = () => { + return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}); +}; +var GLOBALS_ALLOWED = "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error"; +var isGloballyAllowed = makeMap(GLOBALS_ALLOWED); +function normalizeStyle(value) { + if (isArray(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } else if (isString(value) || isObject(value)) { + return value; + } +} +var listDelimiterRE = /;(?![^(]*\))/g; +var propertyDelimiterRE = /:([^]+)/; +var styleCommentRE = /\/\*[^]*?\*\//g; +function parseStringStyle(cssText) { + const ret = {}; + cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; +} +function stringifyStyle(styles) { + let ret = ""; + if (!styles || isString(styles)) { + return ret; + } + for (const key in styles) { + const value = styles[key]; + if (isString(value) || typeof value === "number") { + const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); + ret += `${normalizedKey}:${value};`; + } + } + return ret; +} +function normalizeClass(value) { + let res = ""; + if (isString(value)) { + res = value; + } else if (isArray(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + " "; + } + } + } else if (isObject(value)) { + for (const name in value) { + if (value[name]) { + res += name + " "; + } + } + } + return res.trim(); +} +function normalizeProps(props) { + if (!props) return null; + let { class: klass, style } = props; + if (klass && !isString(klass)) { + props.class = normalizeClass(klass); + } + if (style) { + props.style = normalizeStyle(style); + } + return props; +} +var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot"; +var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view"; +var MATH_TAGS = "annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics"; +var VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr"; +var isHTMLTag = makeMap(HTML_TAGS); +var isSVGTag = makeMap(SVG_TAGS); +var isMathMLTag = makeMap(MATH_TAGS); +var isVoidTag = makeMap(VOID_TAGS); +var specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; +var isSpecialBooleanAttr = makeMap(specialBooleanAttrs); +var isBooleanAttr = makeMap( + specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected` +); +function includeBooleanAttr(value) { + return !!value || value === ""; +} +var isKnownHtmlAttr = makeMap( + `accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap` +); +var isKnownSvgAttr = makeMap( + `xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan` +); +function isRenderableAttrValue(value) { + if (value == null) { + return false; + } + const type = typeof value; + return type === "string" || type === "number" || type === "boolean"; +} +function looseCompareArrays(a, b) { + if (a.length !== b.length) return false; + let equal = true; + for (let i = 0; equal && i < a.length; i++) { + equal = looseEqual(a[i], b[i]); + } + return equal; +} +function looseEqual(a, b) { + if (a === b) return true; + let aValidType = isDate(a); + let bValidType = isDate(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? a.getTime() === b.getTime() : false; + } + aValidType = isSymbol(a); + bValidType = isSymbol(b); + if (aValidType || bValidType) { + return a === b; + } + aValidType = isArray(a); + bValidType = isArray(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? looseCompareArrays(a, b) : false; + } + aValidType = isObject(a); + bValidType = isObject(b); + if (aValidType || bValidType) { + if (!aValidType || !bValidType) { + return false; + } + const aKeysCount = Object.keys(a).length; + const bKeysCount = Object.keys(b).length; + if (aKeysCount !== bKeysCount) { + return false; + } + for (const key in a) { + const aHasKey = a.hasOwnProperty(key); + const bHasKey = b.hasOwnProperty(key); + if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { + return false; + } + } + } + return String(a) === String(b); +} +function looseIndexOf(arr, val) { + return arr.findIndex((item) => looseEqual(item, val)); +} +var isRef = (val) => { + return !!(val && val.__v_isRef === true); +}; +var toDisplayString = (val) => { + return isString(val) ? val : val == null ? "" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? isRef(val) ? toDisplayString(val.value) : JSON.stringify(val, replacer, 2) : String(val); +}; +var replacer = (_key, val) => { + if (isRef(val)) { + return replacer(_key, val.value); + } else if (isMap(val)) { + return { + [`Map(${val.size})`]: [...val.entries()].reduce( + (entries, [key, val2], i) => { + entries[stringifySymbol(key, i) + " =>"] = val2; + return entries; + }, + {} + ) + }; + } else if (isSet(val)) { + return { + [`Set(${val.size})`]: [...val.values()].map((v) => stringifySymbol(v)) + }; + } else if (isSymbol(val)) { + return stringifySymbol(val); + } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { + return String(val); + } + return val; +}; +var stringifySymbol = (v, i = "") => { + var _a; + return ( + // Symbol.description in es2019+ so we need to cast here to pass + // the lib: es2016 check + isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i})` : v + ); +}; + +// node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js +function warn(msg, ...args) { + console.warn(`[Vue warn] ${msg}`, ...args); +} +var activeEffectScope; +var EffectScope = class { + constructor(detached = false) { + this.detached = detached; + this._active = true; + this.effects = []; + this.cleanups = []; + this.parent = activeEffectScope; + if (!detached && activeEffectScope) { + this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( + this + ) - 1; + } + } + get active() { + return this._active; + } + run(fn) { + if (this._active) { + const currentEffectScope = activeEffectScope; + try { + activeEffectScope = this; + return fn(); + } finally { + activeEffectScope = currentEffectScope; + } + } else if (true) { + warn(`cannot run an inactive effect scope.`); + } + } + /** + * This should only be called on non-detached scopes + * @internal + */ + on() { + activeEffectScope = this; + } + /** + * This should only be called on non-detached scopes + * @internal + */ + off() { + activeEffectScope = this.parent; + } + stop(fromParent) { + if (this._active) { + let i, l; + for (i = 0, l = this.effects.length; i < l; i++) { + this.effects[i].stop(); + } + for (i = 0, l = this.cleanups.length; i < l; i++) { + this.cleanups[i](); + } + if (this.scopes) { + for (i = 0, l = this.scopes.length; i < l; i++) { + this.scopes[i].stop(true); + } + } + if (!this.detached && this.parent && !fromParent) { + const last = this.parent.scopes.pop(); + if (last && last !== this) { + this.parent.scopes[this.index] = last; + last.index = this.index; + } + } + this.parent = void 0; + this._active = false; + } + } +}; +function effectScope(detached) { + return new EffectScope(detached); +} +function recordEffectScope(effect2, scope = activeEffectScope) { + if (scope && scope.active) { + scope.effects.push(effect2); + } +} +function getCurrentScope() { + return activeEffectScope; +} +function onScopeDispose(fn) { + if (activeEffectScope) { + activeEffectScope.cleanups.push(fn); + } else if (true) { + warn( + `onScopeDispose() is called when there is no active effect scope to be associated with.` + ); + } +} +var activeEffect; +var ReactiveEffect = class { + constructor(fn, trigger2, scheduler, scope) { + this.fn = fn; + this.trigger = trigger2; + this.scheduler = scheduler; + this.active = true; + this.deps = []; + this._dirtyLevel = 4; + this._trackId = 0; + this._runnings = 0; + this._shouldSchedule = false; + this._depsLength = 0; + recordEffectScope(this, scope); + } + get dirty() { + if (this._dirtyLevel === 2 || this._dirtyLevel === 3) { + this._dirtyLevel = 1; + pauseTracking(); + for (let i = 0; i < this._depsLength; i++) { + const dep = this.deps[i]; + if (dep.computed) { + triggerComputed(dep.computed); + if (this._dirtyLevel >= 4) { + break; + } + } + } + if (this._dirtyLevel === 1) { + this._dirtyLevel = 0; + } + resetTracking(); + } + return this._dirtyLevel >= 4; + } + set dirty(v) { + this._dirtyLevel = v ? 4 : 0; + } + run() { + this._dirtyLevel = 0; + if (!this.active) { + return this.fn(); + } + let lastShouldTrack = shouldTrack; + let lastEffect = activeEffect; + try { + shouldTrack = true; + activeEffect = this; + this._runnings++; + preCleanupEffect(this); + return this.fn(); + } finally { + postCleanupEffect(this); + this._runnings--; + activeEffect = lastEffect; + shouldTrack = lastShouldTrack; + } + } + stop() { + if (this.active) { + preCleanupEffect(this); + postCleanupEffect(this); + this.onStop && this.onStop(); + this.active = false; + } + } +}; +function triggerComputed(computed3) { + return computed3.value; +} +function preCleanupEffect(effect2) { + effect2._trackId++; + effect2._depsLength = 0; +} +function postCleanupEffect(effect2) { + if (effect2.deps.length > effect2._depsLength) { + for (let i = effect2._depsLength; i < effect2.deps.length; i++) { + cleanupDepEffect(effect2.deps[i], effect2); + } + effect2.deps.length = effect2._depsLength; + } +} +function cleanupDepEffect(dep, effect2) { + const trackId = dep.get(effect2); + if (trackId !== void 0 && effect2._trackId !== trackId) { + dep.delete(effect2); + if (dep.size === 0) { + dep.cleanup(); + } + } +} +function effect(fn, options) { + if (fn.effect instanceof ReactiveEffect) { + fn = fn.effect.fn; + } + const _effect = new ReactiveEffect(fn, NOOP, () => { + if (_effect.dirty) { + _effect.run(); + } + }); + if (options) { + extend(_effect, options); + if (options.scope) recordEffectScope(_effect, options.scope); + } + if (!options || !options.lazy) { + _effect.run(); + } + const runner = _effect.run.bind(_effect); + runner.effect = _effect; + return runner; +} +function stop(runner) { + runner.effect.stop(); +} +var shouldTrack = true; +var pauseScheduleStack = 0; +var trackStack = []; +function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; +} +function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === void 0 ? true : last; +} +function pauseScheduling() { + pauseScheduleStack++; +} +function resetScheduling() { + pauseScheduleStack--; + while (!pauseScheduleStack && queueEffectSchedulers.length) { + queueEffectSchedulers.shift()(); + } +} +function trackEffect(effect2, dep, debuggerEventExtraInfo) { + var _a; + if (dep.get(effect2) !== effect2._trackId) { + dep.set(effect2, effect2._trackId); + const oldDep = effect2.deps[effect2._depsLength]; + if (oldDep !== dep) { + if (oldDep) { + cleanupDepEffect(oldDep, effect2); + } + effect2.deps[effect2._depsLength++] = dep; + } else { + effect2._depsLength++; + } + if (true) { + (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo)); + } + } +} +var queueEffectSchedulers = []; +function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) { + var _a; + pauseScheduling(); + for (const effect2 of dep.keys()) { + let tracking; + if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) { + effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0); + effect2._dirtyLevel = dirtyLevel; + } + if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) { + if (true) { + (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo)); + } + effect2.trigger(); + if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) { + effect2._shouldSchedule = false; + if (effect2.scheduler) { + queueEffectSchedulers.push(effect2.scheduler); + } + } + } + } + resetScheduling(); +} +var createDep = (cleanup, computed3) => { + const dep = /* @__PURE__ */ new Map(); + dep.cleanup = cleanup; + dep.computed = computed3; + return dep; +}; +var targetMap = /* @__PURE__ */ new WeakMap(); +var ITERATE_KEY = Symbol(true ? "iterate" : ""); +var MAP_KEY_ITERATE_KEY = Symbol(true ? "Map key iterate" : ""); +function track(target, type, key) { + if (shouldTrack && activeEffect) { + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, depsMap = /* @__PURE__ */ new Map()); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, dep = createDep(() => depsMap.delete(key))); + } + trackEffect( + activeEffect, + dep, + true ? { + target, + type, + key + } : void 0 + ); + } +} +function trigger(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + return; + } + let deps = []; + if (type === "clear") { + deps = [...depsMap.values()]; + } else if (key === "length" && isArray(target)) { + const newLength = Number(newValue); + depsMap.forEach((dep, key2) => { + if (key2 === "length" || !isSymbol(key2) && key2 >= newLength) { + deps.push(dep); + } + }); + } else { + if (key !== void 0) { + deps.push(depsMap.get(key)); + } + switch (type) { + case "add": + if (!isArray(target)) { + deps.push(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } else if (isIntegerKey(key)) { + deps.push(depsMap.get("length")); + } + break; + case "delete": + if (!isArray(target)) { + deps.push(depsMap.get(ITERATE_KEY)); + if (isMap(target)) { + deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set": + if (isMap(target)) { + deps.push(depsMap.get(ITERATE_KEY)); + } + break; + } + } + pauseScheduling(); + for (const dep of deps) { + if (dep) { + triggerEffects( + dep, + 4, + true ? { + target, + type, + key, + newValue, + oldValue, + oldTarget + } : void 0 + ); + } + } + resetScheduling(); +} +function getDepFromReactive(object, key) { + const depsMap = targetMap.get(object); + return depsMap && depsMap.get(key); +} +var isNonTrackableKeys = makeMap(`__proto__,__v_isRef,__isVue`); +var builtInSymbols = new Set( + Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol) +); +var arrayInstrumentations = createArrayInstrumentations(); +function createArrayInstrumentations() { + const instrumentations = {}; + ["includes", "indexOf", "lastIndexOf"].forEach((key) => { + instrumentations[key] = function(...args) { + const arr = toRaw(this); + for (let i = 0, l = this.length; i < l; i++) { + track(arr, "get", i + ""); + } + const res = arr[key](...args); + if (res === -1 || res === false) { + return arr[key](...args.map(toRaw)); + } else { + return res; + } + }; + }); + ["push", "pop", "shift", "unshift", "splice"].forEach((key) => { + instrumentations[key] = function(...args) { + pauseTracking(); + pauseScheduling(); + const res = toRaw(this)[key].apply(this, args); + resetScheduling(); + resetTracking(); + return res; + }; + }); + return instrumentations; +} +function hasOwnProperty2(key) { + if (!isSymbol(key)) key = String(key); + const obj = toRaw(this); + track(obj, "has", key); + return obj.hasOwnProperty(key); +} +var BaseReactiveHandler = class { + constructor(_isReadonly = false, _isShallow = false) { + this._isReadonly = _isReadonly; + this._isShallow = _isShallow; + } + get(target, key, receiver) { + const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow; + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_isShallow") { + return isShallow2; + } else if (key === "__v_raw") { + if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype + // this means the receiver is a user proxy of the reactive proxy + Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) { + return target; + } + return; + } + const targetIsArray = isArray(target); + if (!isReadonly2) { + if (targetIsArray && hasOwn(arrayInstrumentations, key)) { + return Reflect.get(arrayInstrumentations, key, receiver); + } + if (key === "hasOwnProperty") { + return hasOwnProperty2; + } + } + const res = Reflect.get(target, key, receiver); + if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { + return res; + } + if (!isReadonly2) { + track(target, "get", key); + } + if (isShallow2) { + return res; + } + if (isRef2(res)) { + return targetIsArray && isIntegerKey(key) ? res : res.value; + } + if (isObject(res)) { + return isReadonly2 ? readonly(res) : reactive(res); + } + return res; + } +}; +var MutableReactiveHandler = class extends BaseReactiveHandler { + constructor(isShallow2 = false) { + super(false, isShallow2); + } + set(target, key, value, receiver) { + let oldValue = target[key]; + if (!this._isShallow) { + const isOldValueReadonly = isReadonly(oldValue); + if (!isShallow(value) && !isReadonly(value)) { + oldValue = toRaw(oldValue); + value = toRaw(value); + } + if (!isArray(target) && isRef2(oldValue) && !isRef2(value)) { + if (isOldValueReadonly) { + return false; + } else { + oldValue.value = value; + return true; + } + } + } + const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key); + const result = Reflect.set(target, key, value, receiver); + if (target === toRaw(receiver)) { + if (!hadKey) { + trigger(target, "add", key, value); + } else if (hasChanged(value, oldValue)) { + trigger(target, "set", key, value, oldValue); + } + } + return result; + } + deleteProperty(target, key) { + const hadKey = hasOwn(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger(target, "delete", key, void 0, oldValue); + } + return result; + } + has(target, key) { + const result = Reflect.has(target, key); + if (!isSymbol(key) || !builtInSymbols.has(key)) { + track(target, "has", key); + } + return result; + } + ownKeys(target) { + track( + target, + "iterate", + isArray(target) ? "length" : ITERATE_KEY + ); + return Reflect.ownKeys(target); + } +}; +var ReadonlyReactiveHandler = class extends BaseReactiveHandler { + constructor(isShallow2 = false) { + super(true, isShallow2); + } + set(target, key) { + if (true) { + warn( + `Set operation on key "${String(key)}" failed: target is readonly.`, + target + ); + } + return true; + } + deleteProperty(target, key) { + if (true) { + warn( + `Delete operation on key "${String(key)}" failed: target is readonly.`, + target + ); + } + return true; + } +}; +var mutableHandlers = new MutableReactiveHandler(); +var readonlyHandlers = new ReadonlyReactiveHandler(); +var shallowReactiveHandlers = new MutableReactiveHandler( + true +); +var shallowReadonlyHandlers = new ReadonlyReactiveHandler(true); +var toShallow = (value) => value; +var getProto = (v) => Reflect.getPrototypeOf(v); +function get(target, key, isReadonly2 = false, isShallow2 = false) { + target = target["__v_raw"]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (!isReadonly2) { + if (hasChanged(key, rawKey)) { + track(rawTarget, "get", key); + } + track(rawTarget, "get", rawKey); + } + const { has: has2 } = getProto(rawTarget); + const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive; + if (has2.call(rawTarget, key)) { + return wrap(target.get(key)); + } else if (has2.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } else if (target !== rawTarget) { + target.get(key); + } +} +function has(key, isReadonly2 = false) { + const target = this["__v_raw"]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (!isReadonly2) { + if (hasChanged(key, rawKey)) { + track(rawTarget, "has", key); + } + track(rawTarget, "has", rawKey); + } + return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); +} +function size(target, isReadonly2 = false) { + target = target["__v_raw"]; + !isReadonly2 && track(toRaw(target), "iterate", ITERATE_KEY); + return Reflect.get(target, "size", target); +} +function add(value, _isShallow = false) { + if (!_isShallow && !isShallow(value) && !isReadonly(value)) { + value = toRaw(value); + } + const target = toRaw(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + if (!hadKey) { + target.add(value); + trigger(target, "add", value, value); + } + return this; +} +function set(key, value, _isShallow = false) { + if (!_isShallow && !isShallow(value) && !isReadonly(value)) { + value = toRaw(value); + } + const target = toRaw(this); + const { has: has2, get: get2 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has2.call(target, key); + } else if (true) { + checkIdentityKeys(target, has2, key); + } + const oldValue = get2.call(target, key); + target.set(key, value); + if (!hadKey) { + trigger(target, "add", key, value); + } else if (hasChanged(value, oldValue)) { + trigger(target, "set", key, value, oldValue); + } + return this; +} +function deleteEntry(key) { + const target = toRaw(this); + const { has: has2, get: get2 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has2.call(target, key); + } else if (true) { + checkIdentityKeys(target, has2, key); + } + const oldValue = get2 ? get2.call(target, key) : void 0; + const result = target.delete(key); + if (hadKey) { + trigger(target, "delete", key, void 0, oldValue); + } + return result; +} +function clear() { + const target = toRaw(this); + const hadItems = target.size !== 0; + const oldTarget = true ? isMap(target) ? new Map(target) : new Set(target) : void 0; + const result = target.clear(); + if (hadItems) { + trigger(target, "clear", void 0, void 0, oldTarget); + } + return result; +} +function createForEach(isReadonly2, isShallow2) { + return function forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw"]; + const rawTarget = toRaw(target); + const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track(rawTarget, "iterate", ITERATE_KEY); + return target.forEach((value, key) => { + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + }; +} +function createIterableMethod(method, isReadonly2, isShallow2) { + return function(...args) { + const target = this["__v_raw"]; + const rawTarget = toRaw(target); + const targetIsMap = isMap(rawTarget); + const isPair = method === "entries" || method === Symbol.iterator && targetIsMap; + const isKeyOnly = method === "keys" && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track( + rawTarget, + "iterate", + isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY + ); + return { + // iterator protocol + next() { + const { value, done } = innerIterator.next(); + return done ? { value, done } : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + // iterable protocol + [Symbol.iterator]() { + return this; + } + }; + }; +} +function createReadonlyMethod(type) { + return function(...args) { + if (true) { + const key = args[0] ? `on key "${args[0]}" ` : ``; + warn( + `${capitalize(type)} operation ${key}failed: target is readonly.`, + toRaw(this) + ); + } + return type === "delete" ? false : type === "clear" ? void 0 : this; + }; +} +function createInstrumentations() { + const mutableInstrumentations2 = { + get(key) { + return get(this, key); + }, + get size() { + return size(this); + }, + has, + add, + set, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) + }; + const shallowInstrumentations2 = { + get(key) { + return get(this, key, false, true); + }, + get size() { + return size(this); + }, + has, + add(value) { + return add.call(this, value, true); + }, + set(key, value) { + return set.call(this, key, value, true); + }, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) + }; + const readonlyInstrumentations2 = { + get(key) { + return get(this, key, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has.call(this, key, true); + }, + add: createReadonlyMethod("add"), + set: createReadonlyMethod("set"), + delete: createReadonlyMethod("delete"), + clear: createReadonlyMethod("clear"), + forEach: createForEach(true, false) + }; + const shallowReadonlyInstrumentations2 = { + get(key) { + return get(this, key, true, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has.call(this, key, true); + }, + add: createReadonlyMethod("add"), + set: createReadonlyMethod("set"), + delete: createReadonlyMethod("delete"), + clear: createReadonlyMethod("clear"), + forEach: createForEach(true, true) + }; + const iteratorMethods = [ + "keys", + "values", + "entries", + Symbol.iterator + ]; + iteratorMethods.forEach((method) => { + mutableInstrumentations2[method] = createIterableMethod(method, false, false); + readonlyInstrumentations2[method] = createIterableMethod(method, true, false); + shallowInstrumentations2[method] = createIterableMethod(method, false, true); + shallowReadonlyInstrumentations2[method] = createIterableMethod( + method, + true, + true + ); + }); + return [ + mutableInstrumentations2, + readonlyInstrumentations2, + shallowInstrumentations2, + shallowReadonlyInstrumentations2 + ]; +} +var [ + mutableInstrumentations, + readonlyInstrumentations, + shallowInstrumentations, + shallowReadonlyInstrumentations +] = createInstrumentations(); +function createInstrumentationGetter(isReadonly2, shallow) { + const instrumentations = shallow ? isReadonly2 ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly2 ? readonlyInstrumentations : mutableInstrumentations; + return (target, key, receiver) => { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw") { + return target; + } + return Reflect.get( + hasOwn(instrumentations, key) && key in target ? instrumentations : target, + key, + receiver + ); + }; +} +var mutableCollectionHandlers = { + get: createInstrumentationGetter(false, false) +}; +var shallowCollectionHandlers = { + get: createInstrumentationGetter(false, true) +}; +var readonlyCollectionHandlers = { + get: createInstrumentationGetter(true, false) +}; +var shallowReadonlyCollectionHandlers = { + get: createInstrumentationGetter(true, true) +}; +function checkIdentityKeys(target, has2, key) { + const rawKey = toRaw(key); + if (rawKey !== key && has2.call(target, rawKey)) { + const type = toRawType(target); + warn( + `Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.` + ); + } +} +var reactiveMap = /* @__PURE__ */ new WeakMap(); +var shallowReactiveMap = /* @__PURE__ */ new WeakMap(); +var readonlyMap = /* @__PURE__ */ new WeakMap(); +var shallowReadonlyMap = /* @__PURE__ */ new WeakMap(); +function targetTypeMap(rawType) { + switch (rawType) { + case "Object": + case "Array": + return 1; + case "Map": + case "Set": + case "WeakMap": + case "WeakSet": + return 2; + default: + return 0; + } +} +function getTargetType(value) { + return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value)); +} +function reactive(target) { + if (isReadonly(target)) { + return target; + } + return createReactiveObject( + target, + false, + mutableHandlers, + mutableCollectionHandlers, + reactiveMap + ); +} +function shallowReactive(target) { + return createReactiveObject( + target, + false, + shallowReactiveHandlers, + shallowCollectionHandlers, + shallowReactiveMap + ); +} +function readonly(target) { + return createReactiveObject( + target, + true, + readonlyHandlers, + readonlyCollectionHandlers, + readonlyMap + ); +} +function shallowReadonly(target) { + return createReactiveObject( + target, + true, + shallowReadonlyHandlers, + shallowReadonlyCollectionHandlers, + shallowReadonlyMap + ); +} +function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) { + if (!isObject(target)) { + if (true) { + warn( + `value cannot be made ${isReadonly2 ? "readonly" : "reactive"}: ${String( + target + )}` + ); + } + return target; + } + if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) { + return target; + } + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + const targetType = getTargetType(target); + if (targetType === 0) { + return target; + } + const proxy = new Proxy( + target, + targetType === 2 ? collectionHandlers : baseHandlers + ); + proxyMap.set(target, proxy); + return proxy; +} +function isReactive(value) { + if (isReadonly(value)) { + return isReactive(value["__v_raw"]); + } + return !!(value && value["__v_isReactive"]); +} +function isReadonly(value) { + return !!(value && value["__v_isReadonly"]); +} +function isShallow(value) { + return !!(value && value["__v_isShallow"]); +} +function isProxy(value) { + return value ? !!value["__v_raw"] : false; +} +function toRaw(observed) { + const raw = observed && observed["__v_raw"]; + return raw ? toRaw(raw) : observed; +} +function markRaw(value) { + if (Object.isExtensible(value)) { + def(value, "__v_skip", true); + } + return value; +} +var toReactive = (value) => isObject(value) ? reactive(value) : value; +var toReadonly = (value) => isObject(value) ? readonly(value) : value; +var COMPUTED_SIDE_EFFECT_WARN = `Computed is still dirty after getter evaluation, likely because a computed is mutating its own dependency in its getter. State mutations in computed getters should be avoided. Check the docs for more details: https://vuejs.org/guide/essentials/computed.html#getters-should-be-side-effect-free`; +var ComputedRefImpl = class { + constructor(getter, _setter, isReadonly2, isSSR) { + this.getter = getter; + this._setter = _setter; + this.dep = void 0; + this.__v_isRef = true; + this["__v_isReadonly"] = false; + this.effect = new ReactiveEffect( + () => getter(this._value), + () => triggerRefValue( + this, + this.effect._dirtyLevel === 2 ? 2 : 3 + ) + ); + this.effect.computed = this; + this.effect.active = this._cacheable = !isSSR; + this["__v_isReadonly"] = isReadonly2; + } + get value() { + const self2 = toRaw(this); + if ((!self2._cacheable || self2.effect.dirty) && hasChanged(self2._value, self2._value = self2.effect.run())) { + triggerRefValue(self2, 4); + } + trackRefValue(self2); + if (self2.effect._dirtyLevel >= 2) { + if (this._warnRecursive) { + warn(COMPUTED_SIDE_EFFECT_WARN, ` + +getter: `, this.getter); + } + triggerRefValue(self2, 2); + } + return self2._value; + } + set value(newValue) { + this._setter(newValue); + } + // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x + get _dirty() { + return this.effect.dirty; + } + set _dirty(v) { + this.effect.dirty = v; + } + // #endregion +}; +function computed(getterOrOptions, debugOptions, isSSR = false) { + let getter; + let setter; + const onlyGetter = isFunction(getterOrOptions); + if (onlyGetter) { + getter = getterOrOptions; + setter = true ? () => { + warn("Write operation failed: computed value is readonly"); + } : NOOP; + } else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR); + if (debugOptions && !isSSR) { + cRef.effect.onTrack = debugOptions.onTrack; + cRef.effect.onTrigger = debugOptions.onTrigger; + } + return cRef; +} +function trackRefValue(ref2) { + var _a; + if (shouldTrack && activeEffect) { + ref2 = toRaw(ref2); + trackEffect( + activeEffect, + (_a = ref2.dep) != null ? _a : ref2.dep = createDep( + () => ref2.dep = void 0, + ref2 instanceof ComputedRefImpl ? ref2 : void 0 + ), + true ? { + target: ref2, + type: "get", + key: "value" + } : void 0 + ); + } +} +function triggerRefValue(ref2, dirtyLevel = 4, newVal, oldVal) { + ref2 = toRaw(ref2); + const dep = ref2.dep; + if (dep) { + triggerEffects( + dep, + dirtyLevel, + true ? { + target: ref2, + type: "set", + key: "value", + newValue: newVal, + oldValue: oldVal + } : void 0 + ); + } +} +function isRef2(r) { + return !!(r && r.__v_isRef === true); +} +function ref(value) { + return createRef(value, false); +} +function shallowRef(value) { + return createRef(value, true); +} +function createRef(rawValue, shallow) { + if (isRef2(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); +} +var RefImpl = class { + constructor(value, __v_isShallow) { + this.__v_isShallow = __v_isShallow; + this.dep = void 0; + this.__v_isRef = true; + this._rawValue = __v_isShallow ? value : toRaw(value); + this._value = __v_isShallow ? value : toReactive(value); + } + get value() { + trackRefValue(this); + return this._value; + } + set value(newVal) { + const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal); + newVal = useDirectValue ? newVal : toRaw(newVal); + if (hasChanged(newVal, this._rawValue)) { + const oldVal = this._rawValue; + this._rawValue = newVal; + this._value = useDirectValue ? newVal : toReactive(newVal); + triggerRefValue(this, 4, newVal, oldVal); + } + } +}; +function triggerRef(ref2) { + triggerRefValue(ref2, 4, true ? ref2.value : void 0); +} +function unref(ref2) { + return isRef2(ref2) ? ref2.value : ref2; +} +function toValue(source) { + return isFunction(source) ? source() : unref(source); +} +var shallowUnwrapHandlers = { + get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef2(oldValue) && !isRef2(value)) { + oldValue.value = value; + return true; + } else { + return Reflect.set(target, key, value, receiver); + } + } +}; +function proxyRefs(objectWithRefs) { + return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); +} +var CustomRefImpl = class { + constructor(factory) { + this.dep = void 0; + this.__v_isRef = true; + const { get: get2, set: set2 } = factory( + () => trackRefValue(this), + () => triggerRefValue(this) + ); + this._get = get2; + this._set = set2; + } + get value() { + return this._get(); + } + set value(newVal) { + this._set(newVal); + } +}; +function customRef(factory) { + return new CustomRefImpl(factory); +} +function toRefs(object) { + if (!isProxy(object)) { + warn(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = propertyToRef(object, key); + } + return ret; +} +var ObjectRefImpl = class { + constructor(_object, _key, _defaultValue) { + this._object = _object; + this._key = _key; + this._defaultValue = _defaultValue; + this.__v_isRef = true; + } + get value() { + const val = this._object[this._key]; + return val === void 0 ? this._defaultValue : val; + } + set value(newVal) { + this._object[this._key] = newVal; + } + get dep() { + return getDepFromReactive(toRaw(this._object), this._key); + } +}; +var GetterRefImpl = class { + constructor(_getter) { + this._getter = _getter; + this.__v_isRef = true; + this.__v_isReadonly = true; + } + get value() { + return this._getter(); + } +}; +function toRef(source, key, defaultValue) { + if (isRef2(source)) { + return source; + } else if (isFunction(source)) { + return new GetterRefImpl(source); + } else if (isObject(source) && arguments.length > 1) { + return propertyToRef(source, key, defaultValue); + } else { + return ref(source); + } +} +function propertyToRef(source, key, defaultValue) { + const val = source[key]; + return isRef2(val) ? val : new ObjectRefImpl(source, key, defaultValue); +} +var TrackOpTypes = { + "GET": "get", + "HAS": "has", + "ITERATE": "iterate" +}; +var TriggerOpTypes = { + "SET": "set", + "ADD": "add", + "DELETE": "delete", + "CLEAR": "clear" +}; + +// node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +var stack = []; +function pushWarningContext(vnode) { + stack.push(vnode); +} +function popWarningContext() { + stack.pop(); +} +var isWarning = false; +function warn$1(msg, ...args) { + if (isWarning) return; + isWarning = true; + pauseTracking(); + const instance = stack.length ? stack[stack.length - 1].component : null; + const appWarnHandler = instance && instance.appContext.config.warnHandler; + const trace = getComponentTrace(); + if (appWarnHandler) { + callWithErrorHandling( + appWarnHandler, + instance, + 11, + [ + // eslint-disable-next-line no-restricted-syntax + msg + args.map((a) => { + var _a, _b; + return (_b = (_a = a.toString) == null ? void 0 : _a.call(a)) != null ? _b : JSON.stringify(a); + }).join(""), + instance && instance.proxy, + trace.map( + ({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>` + ).join("\n"), + trace + ] + ); + } else { + const warnArgs = [`[Vue warn]: ${msg}`, ...args]; + if (trace.length && // avoid spamming console during tests + true) { + warnArgs.push(` +`, ...formatTrace(trace)); + } + console.warn(...warnArgs); + } + resetTracking(); + isWarning = false; +} +function getComponentTrace() { + let currentVNode = stack[stack.length - 1]; + if (!currentVNode) { + return []; + } + const normalizedStack = []; + while (currentVNode) { + const last = normalizedStack[0]; + if (last && last.vnode === currentVNode) { + last.recurseCount++; + } else { + normalizedStack.push({ + vnode: currentVNode, + recurseCount: 0 + }); + } + const parentInstance = currentVNode.component && currentVNode.component.parent; + currentVNode = parentInstance && parentInstance.vnode; + } + return normalizedStack; +} +function formatTrace(trace) { + const logs = []; + trace.forEach((entry, i) => { + logs.push(...i === 0 ? [] : [` +`], ...formatTraceEntry(entry)); + }); + return logs; +} +function formatTraceEntry({ vnode, recurseCount }) { + const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; + const isRoot = vnode.component ? vnode.component.parent == null : false; + const open = ` at <${formatComponentName( + vnode.component, + vnode.type, + isRoot + )}`; + const close = `>` + postfix; + return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; +} +function formatProps(props) { + const res = []; + const keys = Object.keys(props); + keys.slice(0, 3).forEach((key) => { + res.push(...formatProp(key, props[key])); + }); + if (keys.length > 3) { + res.push(` ...`); + } + return res; +} +function formatProp(key, value, raw) { + if (isString(value)) { + value = JSON.stringify(value); + return raw ? value : [`${key}=${value}`]; + } else if (typeof value === "number" || typeof value === "boolean" || value == null) { + return raw ? value : [`${key}=${value}`]; + } else if (isRef2(value)) { + value = formatProp(key, toRaw(value.value), true); + return raw ? value : [`${key}=Ref<`, value, `>`]; + } else if (isFunction(value)) { + return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; + } else { + value = toRaw(value); + return raw ? value : [`${key}=`, value]; + } +} +function assertNumber(val, type) { + if (false) return; + if (val === void 0) { + return; + } else if (typeof val !== "number") { + warn$1(`${type} is not a valid number - got ${JSON.stringify(val)}.`); + } else if (isNaN(val)) { + warn$1(`${type} is NaN - the duration expression might be incorrect.`); + } +} +var ErrorCodes = { + "SETUP_FUNCTION": 0, + "0": "SETUP_FUNCTION", + "RENDER_FUNCTION": 1, + "1": "RENDER_FUNCTION", + "WATCH_GETTER": 2, + "2": "WATCH_GETTER", + "WATCH_CALLBACK": 3, + "3": "WATCH_CALLBACK", + "WATCH_CLEANUP": 4, + "4": "WATCH_CLEANUP", + "NATIVE_EVENT_HANDLER": 5, + "5": "NATIVE_EVENT_HANDLER", + "COMPONENT_EVENT_HANDLER": 6, + "6": "COMPONENT_EVENT_HANDLER", + "VNODE_HOOK": 7, + "7": "VNODE_HOOK", + "DIRECTIVE_HOOK": 8, + "8": "DIRECTIVE_HOOK", + "TRANSITION_HOOK": 9, + "9": "TRANSITION_HOOK", + "APP_ERROR_HANDLER": 10, + "10": "APP_ERROR_HANDLER", + "APP_WARN_HANDLER": 11, + "11": "APP_WARN_HANDLER", + "FUNCTION_REF": 12, + "12": "FUNCTION_REF", + "ASYNC_COMPONENT_LOADER": 13, + "13": "ASYNC_COMPONENT_LOADER", + "SCHEDULER": 14, + "14": "SCHEDULER", + "COMPONENT_UPDATE": 15, + "15": "COMPONENT_UPDATE" +}; +var ErrorTypeStrings$1 = { + ["sp"]: "serverPrefetch hook", + ["bc"]: "beforeCreate hook", + ["c"]: "created hook", + ["bm"]: "beforeMount hook", + ["m"]: "mounted hook", + ["bu"]: "beforeUpdate hook", + ["u"]: "updated", + ["bum"]: "beforeUnmount hook", + ["um"]: "unmounted hook", + ["a"]: "activated hook", + ["da"]: "deactivated hook", + ["ec"]: "errorCaptured hook", + ["rtc"]: "renderTracked hook", + ["rtg"]: "renderTriggered hook", + [0]: "setup function", + [1]: "render function", + [2]: "watcher getter", + [3]: "watcher callback", + [4]: "watcher cleanup function", + [5]: "native event handler", + [6]: "component event handler", + [7]: "vnode hook", + [8]: "directive hook", + [9]: "transition hook", + [10]: "app errorHandler", + [11]: "app warnHandler", + [12]: "ref function", + [13]: "async component loader", + [14]: "scheduler flush", + [15]: "component update" +}; +function callWithErrorHandling(fn, instance, type, args) { + try { + return args ? fn(...args) : fn(); + } catch (err) { + handleError(err, instance, type); + } +} +function callWithAsyncErrorHandling(fn, instance, type, args) { + if (isFunction(fn)) { + const res = callWithErrorHandling(fn, instance, type, args); + if (res && isPromise(res)) { + res.catch((err) => { + handleError(err, instance, type); + }); + } + return res; + } + if (isArray(fn)) { + const values = []; + for (let i = 0; i < fn.length; i++) { + values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); + } + return values; + } else if (true) { + warn$1( + `Invalid value type passed to callWithAsyncErrorHandling(): ${typeof fn}` + ); + } +} +function handleError(err, instance, type, throwInDev = true) { + const contextVNode = instance ? instance.vnode : null; + if (instance) { + let cur = instance.parent; + const exposedInstance = instance.proxy; + const errorInfo = true ? ErrorTypeStrings$1[type] : `https://vuejs.org/error-reference/#runtime-${type}`; + while (cur) { + const errorCapturedHooks = cur.ec; + if (errorCapturedHooks) { + for (let i = 0; i < errorCapturedHooks.length; i++) { + if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { + return; + } + } + } + cur = cur.parent; + } + const appErrorHandler = instance.appContext.config.errorHandler; + if (appErrorHandler) { + pauseTracking(); + callWithErrorHandling( + appErrorHandler, + null, + 10, + [err, exposedInstance, errorInfo] + ); + resetTracking(); + return; + } + } + logError(err, type, contextVNode, throwInDev); +} +function logError(err, type, contextVNode, throwInDev = true) { + if (true) { + const info = ErrorTypeStrings$1[type]; + if (contextVNode) { + pushWarningContext(contextVNode); + } + warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`); + if (contextVNode) { + popWarningContext(); + } + if (throwInDev) { + throw err; + } else { + console.error(err); + } + } else { + console.error(err); + } +} +var isFlushing = false; +var isFlushPending = false; +var queue = []; +var flushIndex = 0; +var pendingPostFlushCbs = []; +var activePostFlushCbs = null; +var postFlushIndex = 0; +var resolvedPromise = Promise.resolve(); +var currentFlushPromise = null; +var RECURSION_LIMIT = 100; +function nextTick(fn) { + const p2 = currentFlushPromise || resolvedPromise; + return fn ? p2.then(this ? fn.bind(this) : fn) : p2; +} +function findInsertionIndex(id) { + let start = flushIndex + 1; + let end = queue.length; + while (start < end) { + const middle = start + end >>> 1; + const middleJob = queue[middle]; + const middleJobId = getId(middleJob); + if (middleJobId < id || middleJobId === id && middleJob.pre) { + start = middle + 1; + } else { + end = middle; + } + } + return start; +} +function queueJob(job) { + if (!queue.length || !queue.includes( + job, + isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex + )) { + if (job.id == null) { + queue.push(job); + } else { + queue.splice(findInsertionIndex(job.id), 0, job); + } + queueFlush(); + } +} +function queueFlush() { + if (!isFlushing && !isFlushPending) { + isFlushPending = true; + currentFlushPromise = resolvedPromise.then(flushJobs); + } +} +function invalidateJob(job) { + const i = queue.indexOf(job); + if (i > flushIndex) { + queue.splice(i, 1); + } +} +function queuePostFlushCb(cb) { + if (!isArray(cb)) { + if (!activePostFlushCbs || !activePostFlushCbs.includes( + cb, + cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex + )) { + pendingPostFlushCbs.push(cb); + } + } else { + pendingPostFlushCbs.push(...cb); + } + queueFlush(); +} +function flushPreFlushCbs(instance, seen, i = isFlushing ? flushIndex + 1 : 0) { + if (true) { + seen = seen || /* @__PURE__ */ new Map(); + } + for (; i < queue.length; i++) { + const cb = queue[i]; + if (cb && cb.pre) { + if (instance && cb.id !== instance.uid) { + continue; + } + if (checkRecursiveUpdates(seen, cb)) { + continue; + } + queue.splice(i, 1); + i--; + cb(); + } + } +} +function flushPostFlushCbs(seen) { + if (pendingPostFlushCbs.length) { + const deduped = [...new Set(pendingPostFlushCbs)].sort( + (a, b) => getId(a) - getId(b) + ); + pendingPostFlushCbs.length = 0; + if (activePostFlushCbs) { + activePostFlushCbs.push(...deduped); + return; + } + activePostFlushCbs = deduped; + if (true) { + seen = seen || /* @__PURE__ */ new Map(); + } + for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { + const cb = activePostFlushCbs[postFlushIndex]; + if (checkRecursiveUpdates(seen, cb)) { + continue; + } + if (cb.active !== false) cb(); + } + activePostFlushCbs = null; + postFlushIndex = 0; + } +} +var getId = (job) => job.id == null ? Infinity : job.id; +var comparator = (a, b) => { + const diff = getId(a) - getId(b); + if (diff === 0) { + if (a.pre && !b.pre) return -1; + if (b.pre && !a.pre) return 1; + } + return diff; +}; +function flushJobs(seen) { + isFlushPending = false; + isFlushing = true; + if (true) { + seen = seen || /* @__PURE__ */ new Map(); + } + queue.sort(comparator); + const check = true ? (job) => checkRecursiveUpdates(seen, job) : NOOP; + try { + for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex]; + if (job && job.active !== false) { + if (check(job)) { + continue; + } + callWithErrorHandling( + job, + job.i, + job.i ? 15 : 14 + ); + } + } + } finally { + flushIndex = 0; + queue.length = 0; + flushPostFlushCbs(seen); + isFlushing = false; + currentFlushPromise = null; + if (queue.length || pendingPostFlushCbs.length) { + flushJobs(seen); + } + } +} +function checkRecursiveUpdates(seen, fn) { + if (!seen.has(fn)) { + seen.set(fn, 1); + } else { + const count = seen.get(fn); + if (count > RECURSION_LIMIT) { + const instance = fn.i; + const componentName = instance && getComponentName(instance.type); + handleError( + `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`, + null, + 10 + ); + return true; + } else { + seen.set(fn, count + 1); + } + } +} +var isHmrUpdating = false; +var hmrDirtyComponents = /* @__PURE__ */ new Map(); +if (true) { + getGlobalThis().__VUE_HMR_RUNTIME__ = { + createRecord: tryWrap(createRecord), + rerender: tryWrap(rerender), + reload: tryWrap(reload) + }; +} +var map = /* @__PURE__ */ new Map(); +function registerHMR(instance) { + const id = instance.type.__hmrId; + let record = map.get(id); + if (!record) { + createRecord(id, instance.type); + record = map.get(id); + } + record.instances.add(instance); +} +function unregisterHMR(instance) { + map.get(instance.type.__hmrId).instances.delete(instance); +} +function createRecord(id, initialDef) { + if (map.has(id)) { + return false; + } + map.set(id, { + initialDef: normalizeClassComponent(initialDef), + instances: /* @__PURE__ */ new Set() + }); + return true; +} +function normalizeClassComponent(component) { + return isClassComponent(component) ? component.__vccOpts : component; +} +function rerender(id, newRender) { + const record = map.get(id); + if (!record) { + return; + } + record.initialDef.render = newRender; + [...record.instances].forEach((instance) => { + if (newRender) { + instance.render = newRender; + normalizeClassComponent(instance.type).render = newRender; + } + instance.renderCache = []; + isHmrUpdating = true; + instance.effect.dirty = true; + instance.update(); + isHmrUpdating = false; + }); +} +function reload(id, newComp) { + const record = map.get(id); + if (!record) return; + newComp = normalizeClassComponent(newComp); + updateComponentDef(record.initialDef, newComp); + const instances = [...record.instances]; + for (let i = 0; i < instances.length; i++) { + const instance = instances[i]; + const oldComp = normalizeClassComponent(instance.type); + let dirtyInstances = hmrDirtyComponents.get(oldComp); + if (!dirtyInstances) { + if (oldComp !== record.initialDef) { + updateComponentDef(oldComp, newComp); + } + hmrDirtyComponents.set(oldComp, dirtyInstances = /* @__PURE__ */ new Set()); + } + dirtyInstances.add(instance); + instance.appContext.propsCache.delete(instance.type); + instance.appContext.emitsCache.delete(instance.type); + instance.appContext.optionsCache.delete(instance.type); + if (instance.ceReload) { + dirtyInstances.add(instance); + instance.ceReload(newComp.styles); + dirtyInstances.delete(instance); + } else if (instance.parent) { + instance.parent.effect.dirty = true; + queueJob(() => { + instance.parent.update(); + dirtyInstances.delete(instance); + }); + } else if (instance.appContext.reload) { + instance.appContext.reload(); + } else if (typeof window !== "undefined") { + window.location.reload(); + } else { + console.warn( + "[HMR] Root or manually mounted instance modified. Full reload required." + ); + } + } + queuePostFlushCb(() => { + hmrDirtyComponents.clear(); + }); +} +function updateComponentDef(oldComp, newComp) { + extend(oldComp, newComp); + for (const key in oldComp) { + if (key !== "__file" && !(key in newComp)) { + delete oldComp[key]; + } + } +} +function tryWrap(fn) { + return (id, arg) => { + try { + return fn(id, arg); + } catch (e) { + console.error(e); + console.warn( + `[HMR] Something went wrong during Vue component hot-reload. Full reload required.` + ); + } + }; +} +var devtools$1; +var buffer = []; +var devtoolsNotInstalled = false; +function emit$1(event, ...args) { + if (devtools$1) { + devtools$1.emit(event, ...args); + } else if (!devtoolsNotInstalled) { + buffer.push({ event, args }); + } +} +function setDevtoolsHook$1(hook, target) { + var _a, _b; + devtools$1 = hook; + if (devtools$1) { + devtools$1.enabled = true; + buffer.forEach(({ event, args }) => devtools$1.emit(event, ...args)); + buffer = []; + } else if ( + // handle late devtools injection - only do this if we are in an actual + // browser environment to avoid the timer handle stalling test runner exit + // (#4815) + typeof window !== "undefined" && // some envs mock window but not fully + window.HTMLElement && // also exclude jsdom + // eslint-disable-next-line no-restricted-syntax + !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes("jsdom")) + ) { + const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []; + replay.push((newHook) => { + setDevtoolsHook$1(newHook, target); + }); + setTimeout(() => { + if (!devtools$1) { + target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; + devtoolsNotInstalled = true; + buffer = []; + } + }, 3e3); + } else { + devtoolsNotInstalled = true; + buffer = []; + } +} +function devtoolsInitApp(app, version2) { + emit$1("app:init", app, version2, { + Fragment, + Text, + Comment, + Static + }); +} +function devtoolsUnmountApp(app) { + emit$1("app:unmount", app); +} +var devtoolsComponentAdded = createDevtoolsComponentHook( + "component:added" + /* COMPONENT_ADDED */ +); +var devtoolsComponentUpdated = createDevtoolsComponentHook( + "component:updated" + /* COMPONENT_UPDATED */ +); +var _devtoolsComponentRemoved = createDevtoolsComponentHook( + "component:removed" + /* COMPONENT_REMOVED */ +); +var devtoolsComponentRemoved = (component) => { + if (devtools$1 && typeof devtools$1.cleanupBuffer === "function" && // remove the component if it wasn't buffered + !devtools$1.cleanupBuffer(component)) { + _devtoolsComponentRemoved(component); + } +}; +function createDevtoolsComponentHook(hook) { + return (component) => { + emit$1( + hook, + component.appContext.app, + component.uid, + component.parent ? component.parent.uid : void 0, + component + ); + }; +} +var devtoolsPerfStart = createDevtoolsPerformanceHook( + "perf:start" + /* PERFORMANCE_START */ +); +var devtoolsPerfEnd = createDevtoolsPerformanceHook( + "perf:end" + /* PERFORMANCE_END */ +); +function createDevtoolsPerformanceHook(hook) { + return (component, type, time) => { + emit$1(hook, component.appContext.app, component.uid, component, type, time); + }; +} +function devtoolsComponentEmit(component, event, params) { + emit$1( + "component:emit", + component.appContext.app, + component, + event, + params + ); +} +var currentRenderingInstance = null; +var currentScopeId = null; +function setCurrentRenderingInstance(instance) { + const prev = currentRenderingInstance; + currentRenderingInstance = instance; + currentScopeId = instance && instance.type.__scopeId || null; + return prev; +} +function pushScopeId(id) { + currentScopeId = id; +} +function popScopeId() { + currentScopeId = null; +} +var withScopeId = (_id) => withCtx; +function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot) { + if (!ctx) return fn; + if (fn._n) { + return fn; + } + const renderFnWithContext = (...args) => { + if (renderFnWithContext._d) { + setBlockTracking(-1); + } + const prevInstance = setCurrentRenderingInstance(ctx); + let res; + try { + res = fn(...args); + } finally { + setCurrentRenderingInstance(prevInstance); + if (renderFnWithContext._d) { + setBlockTracking(1); + } + } + if (true) { + devtoolsComponentUpdated(ctx); + } + return res; + }; + renderFnWithContext._n = true; + renderFnWithContext._c = true; + renderFnWithContext._d = true; + return renderFnWithContext; +} +function validateDirectiveName(name) { + if (isBuiltInDirective(name)) { + warn$1("Do not use built-in directive ids as custom directive id: " + name); + } +} +function withDirectives(vnode, directives) { + if (currentRenderingInstance === null) { + warn$1(`withDirectives can only be used inside render functions.`); + return vnode; + } + const instance = getComponentPublicInstance(currentRenderingInstance); + const bindings = vnode.dirs || (vnode.dirs = []); + for (let i = 0; i < directives.length; i++) { + let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; + if (dir) { + if (isFunction(dir)) { + dir = { + mounted: dir, + updated: dir + }; + } + if (dir.deep) { + traverse(value); + } + bindings.push({ + dir, + instance, + value, + oldValue: void 0, + arg, + modifiers + }); + } + } + return vnode; +} +function invokeDirectiveHook(vnode, prevVNode, instance, name) { + const bindings = vnode.dirs; + const oldBindings = prevVNode && prevVNode.dirs; + for (let i = 0; i < bindings.length; i++) { + const binding = bindings[i]; + if (oldBindings) { + binding.oldValue = oldBindings[i].value; + } + let hook = binding.dir[name]; + if (hook) { + pauseTracking(); + callWithAsyncErrorHandling(hook, instance, 8, [ + vnode.el, + binding, + vnode, + prevVNode + ]); + resetTracking(); + } + } +} +var leaveCbKey = Symbol("_leaveCb"); +var enterCbKey = Symbol("_enterCb"); +function useTransitionState() { + const state = { + isMounted: false, + isLeaving: false, + isUnmounting: false, + leavingVNodes: /* @__PURE__ */ new Map() + }; + onMounted(() => { + state.isMounted = true; + }); + onBeforeUnmount(() => { + state.isUnmounting = true; + }); + return state; +} +var TransitionHookValidator = [Function, Array]; +var BaseTransitionPropsValidators = { + mode: String, + appear: Boolean, + persisted: Boolean, + // enter + onBeforeEnter: TransitionHookValidator, + onEnter: TransitionHookValidator, + onAfterEnter: TransitionHookValidator, + onEnterCancelled: TransitionHookValidator, + // leave + onBeforeLeave: TransitionHookValidator, + onLeave: TransitionHookValidator, + onAfterLeave: TransitionHookValidator, + onLeaveCancelled: TransitionHookValidator, + // appear + onBeforeAppear: TransitionHookValidator, + onAppear: TransitionHookValidator, + onAfterAppear: TransitionHookValidator, + onAppearCancelled: TransitionHookValidator +}; +var recursiveGetSubtree = (instance) => { + const subTree = instance.subTree; + return subTree.component ? recursiveGetSubtree(subTree.component) : subTree; +}; +var BaseTransitionImpl = { + name: `BaseTransition`, + props: BaseTransitionPropsValidators, + setup(props, { slots }) { + const instance = getCurrentInstance(); + const state = useTransitionState(); + return () => { + const children = slots.default && getTransitionRawChildren(slots.default(), true); + if (!children || !children.length) { + return; + } + let child = children[0]; + if (children.length > 1) { + let hasFound = false; + for (const c of children) { + if (c.type !== Comment) { + if (hasFound) { + warn$1( + " can only be used on a single element or component. Use for lists." + ); + break; + } + child = c; + hasFound = true; + if (false) break; + } + } + } + const rawProps = toRaw(props); + const { mode } = rawProps; + if (mode && mode !== "in-out" && mode !== "out-in" && mode !== "default") { + warn$1(`invalid mode: ${mode}`); + } + if (state.isLeaving) { + return emptyPlaceholder(child); + } + const innerChild = getKeepAliveChild(child); + if (!innerChild) { + return emptyPlaceholder(child); + } + let enterHooks = resolveTransitionHooks( + innerChild, + rawProps, + state, + instance, + // #11061, ensure enterHooks is fresh after clone + (hooks) => enterHooks = hooks + ); + setTransitionHooks(innerChild, enterHooks); + const oldChild = instance.subTree; + const oldInnerChild = oldChild && getKeepAliveChild(oldChild); + if (oldInnerChild && oldInnerChild.type !== Comment && !isSameVNodeType(innerChild, oldInnerChild) && recursiveGetSubtree(instance).type !== Comment) { + const leavingHooks = resolveTransitionHooks( + oldInnerChild, + rawProps, + state, + instance + ); + setTransitionHooks(oldInnerChild, leavingHooks); + if (mode === "out-in" && innerChild.type !== Comment) { + state.isLeaving = true; + leavingHooks.afterLeave = () => { + state.isLeaving = false; + if (instance.update.active !== false) { + instance.effect.dirty = true; + instance.update(); + } + }; + return emptyPlaceholder(child); + } else if (mode === "in-out" && innerChild.type !== Comment) { + leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { + const leavingVNodesCache = getLeavingNodesForType( + state, + oldInnerChild + ); + leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; + el[leaveCbKey] = () => { + earlyRemove(); + el[leaveCbKey] = void 0; + delete enterHooks.delayedLeave; + }; + enterHooks.delayedLeave = delayedLeave; + }; + } + } + return child; + }; + } +}; +var BaseTransition = BaseTransitionImpl; +function getLeavingNodesForType(state, vnode) { + const { leavingVNodes } = state; + let leavingVNodesCache = leavingVNodes.get(vnode.type); + if (!leavingVNodesCache) { + leavingVNodesCache = /* @__PURE__ */ Object.create(null); + leavingVNodes.set(vnode.type, leavingVNodesCache); + } + return leavingVNodesCache; +} +function resolveTransitionHooks(vnode, props, state, instance, postClone) { + const { + appear, + mode, + persisted = false, + onBeforeEnter, + onEnter, + onAfterEnter, + onEnterCancelled, + onBeforeLeave, + onLeave, + onAfterLeave, + onLeaveCancelled, + onBeforeAppear, + onAppear, + onAfterAppear, + onAppearCancelled + } = props; + const key = String(vnode.key); + const leavingVNodesCache = getLeavingNodesForType(state, vnode); + const callHook3 = (hook, args) => { + hook && callWithAsyncErrorHandling( + hook, + instance, + 9, + args + ); + }; + const callAsyncHook = (hook, args) => { + const done = args[1]; + callHook3(hook, args); + if (isArray(hook)) { + if (hook.every((hook2) => hook2.length <= 1)) done(); + } else if (hook.length <= 1) { + done(); + } + }; + const hooks = { + mode, + persisted, + beforeEnter(el) { + let hook = onBeforeEnter; + if (!state.isMounted) { + if (appear) { + hook = onBeforeAppear || onBeforeEnter; + } else { + return; + } + } + if (el[leaveCbKey]) { + el[leaveCbKey]( + true + /* cancelled */ + ); + } + const leavingVNode = leavingVNodesCache[key]; + if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el[leaveCbKey]) { + leavingVNode.el[leaveCbKey](); + } + callHook3(hook, [el]); + }, + enter(el) { + let hook = onEnter; + let afterHook = onAfterEnter; + let cancelHook = onEnterCancelled; + if (!state.isMounted) { + if (appear) { + hook = onAppear || onEnter; + afterHook = onAfterAppear || onAfterEnter; + cancelHook = onAppearCancelled || onEnterCancelled; + } else { + return; + } + } + let called = false; + const done = el[enterCbKey] = (cancelled) => { + if (called) return; + called = true; + if (cancelled) { + callHook3(cancelHook, [el]); + } else { + callHook3(afterHook, [el]); + } + if (hooks.delayedLeave) { + hooks.delayedLeave(); + } + el[enterCbKey] = void 0; + }; + if (hook) { + callAsyncHook(hook, [el, done]); + } else { + done(); + } + }, + leave(el, remove2) { + const key2 = String(vnode.key); + if (el[enterCbKey]) { + el[enterCbKey]( + true + /* cancelled */ + ); + } + if (state.isUnmounting) { + return remove2(); + } + callHook3(onBeforeLeave, [el]); + let called = false; + const done = el[leaveCbKey] = (cancelled) => { + if (called) return; + called = true; + remove2(); + if (cancelled) { + callHook3(onLeaveCancelled, [el]); + } else { + callHook3(onAfterLeave, [el]); + } + el[leaveCbKey] = void 0; + if (leavingVNodesCache[key2] === vnode) { + delete leavingVNodesCache[key2]; + } + }; + leavingVNodesCache[key2] = vnode; + if (onLeave) { + callAsyncHook(onLeave, [el, done]); + } else { + done(); + } + }, + clone(vnode2) { + const hooks2 = resolveTransitionHooks( + vnode2, + props, + state, + instance, + postClone + ); + if (postClone) postClone(hooks2); + return hooks2; + } + }; + return hooks; +} +function emptyPlaceholder(vnode) { + if (isKeepAlive(vnode)) { + vnode = cloneVNode(vnode); + vnode.children = null; + return vnode; + } +} +function getKeepAliveChild(vnode) { + if (!isKeepAlive(vnode)) { + return vnode; + } + if (vnode.component) { + return vnode.component.subTree; + } + const { shapeFlag, children } = vnode; + if (children) { + if (shapeFlag & 16) { + return children[0]; + } + if (shapeFlag & 32 && isFunction(children.default)) { + return children.default(); + } + } +} +function setTransitionHooks(vnode, hooks) { + if (vnode.shapeFlag & 6 && vnode.component) { + setTransitionHooks(vnode.component.subTree, hooks); + } else if (vnode.shapeFlag & 128) { + vnode.ssContent.transition = hooks.clone(vnode.ssContent); + vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); + } else { + vnode.transition = hooks; + } +} +function getTransitionRawChildren(children, keepComment = false, parentKey) { + let ret = []; + let keyedFragmentCount = 0; + for (let i = 0; i < children.length; i++) { + let child = children[i]; + const key = parentKey == null ? child.key : String(parentKey) + String(child.key != null ? child.key : i); + if (child.type === Fragment) { + if (child.patchFlag & 128) keyedFragmentCount++; + ret = ret.concat( + getTransitionRawChildren(child.children, keepComment, key) + ); + } else if (keepComment || child.type !== Comment) { + ret.push(key != null ? cloneVNode(child, { key }) : child); + } + } + if (keyedFragmentCount > 1) { + for (let i = 0; i < ret.length; i++) { + ret[i].patchFlag = -2; + } + } + return ret; +} +function defineComponent(options, extraOptions) { + return isFunction(options) ? ( + // #8326: extend call and options.name access are considered side-effects + // by Rollup, so we have to wrap it in a pure-annotated IIFE. + (() => extend({ name: options.name }, extraOptions, { setup: options }))() + ) : options; +} +var isAsyncWrapper = (i) => !!i.type.__asyncLoader; +function defineAsyncComponent(source) { + if (isFunction(source)) { + source = { loader: source }; + } + const { + loader, + loadingComponent, + errorComponent, + delay = 200, + timeout, + // undefined = never times out + suspensible = true, + onError: userOnError + } = source; + let pendingRequest = null; + let resolvedComp; + let retries = 0; + const retry = () => { + retries++; + pendingRequest = null; + return load(); + }; + const load = () => { + let thisRequest; + return pendingRequest || (thisRequest = pendingRequest = loader().catch((err) => { + err = err instanceof Error ? err : new Error(String(err)); + if (userOnError) { + return new Promise((resolve2, reject) => { + const userRetry = () => resolve2(retry()); + const userFail = () => reject(err); + userOnError(err, userRetry, userFail, retries + 1); + }); + } else { + throw err; + } + }).then((comp) => { + if (thisRequest !== pendingRequest && pendingRequest) { + return pendingRequest; + } + if (!comp) { + warn$1( + `Async component loader resolved to undefined. If you are using retry(), make sure to return its return value.` + ); + } + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === "Module")) { + comp = comp.default; + } + if (comp && !isObject(comp) && !isFunction(comp)) { + throw new Error(`Invalid async component load result: ${comp}`); + } + resolvedComp = comp; + return comp; + })); + }; + return defineComponent({ + name: "AsyncComponentWrapper", + __asyncLoader: load, + get __asyncResolved() { + return resolvedComp; + }, + setup() { + const instance = currentInstance; + if (resolvedComp) { + return () => createInnerComp(resolvedComp, instance); + } + const onError = (err) => { + pendingRequest = null; + handleError( + err, + instance, + 13, + !errorComponent + ); + }; + if (suspensible && instance.suspense || isInSSRComponentSetup) { + return load().then((comp) => { + return () => createInnerComp(comp, instance); + }).catch((err) => { + onError(err); + return () => errorComponent ? createVNode(errorComponent, { + error: err + }) : null; + }); + } + const loaded = ref(false); + const error = ref(); + const delayed = ref(!!delay); + if (delay) { + setTimeout(() => { + delayed.value = false; + }, delay); + } + if (timeout != null) { + setTimeout(() => { + if (!loaded.value && !error.value) { + const err = new Error( + `Async component timed out after ${timeout}ms.` + ); + onError(err); + error.value = err; + } + }, timeout); + } + load().then(() => { + loaded.value = true; + if (instance.parent && isKeepAlive(instance.parent.vnode)) { + instance.parent.effect.dirty = true; + queueJob(instance.parent.update); + } + }).catch((err) => { + onError(err); + error.value = err; + }); + return () => { + if (loaded.value && resolvedComp) { + return createInnerComp(resolvedComp, instance); + } else if (error.value && errorComponent) { + return createVNode(errorComponent, { + error: error.value + }); + } else if (loadingComponent && !delayed.value) { + return createVNode(loadingComponent); + } + }; + } + }); +} +function createInnerComp(comp, parent) { + const { ref: ref2, props, children, ce } = parent.vnode; + const vnode = createVNode(comp, props, children); + vnode.ref = ref2; + vnode.ce = ce; + delete parent.vnode.ce; + return vnode; +} +var isKeepAlive = (vnode) => vnode.type.__isKeepAlive; +var KeepAliveImpl = { + name: `KeepAlive`, + // Marker for special handling inside the renderer. We are not using a === + // check directly on KeepAlive in the renderer, because importing it directly + // would prevent it from being tree-shaken. + __isKeepAlive: true, + props: { + include: [String, RegExp, Array], + exclude: [String, RegExp, Array], + max: [String, Number] + }, + setup(props, { slots }) { + const instance = getCurrentInstance(); + const sharedContext = instance.ctx; + if (!sharedContext.renderer) { + return () => { + const children = slots.default && slots.default(); + return children && children.length === 1 ? children[0] : children; + }; + } + const cache = /* @__PURE__ */ new Map(); + const keys = /* @__PURE__ */ new Set(); + let current = null; + if (true) { + instance.__v_cache = cache; + } + const parentSuspense = instance.suspense; + const { + renderer: { + p: patch, + m: move, + um: _unmount, + o: { createElement } + } + } = sharedContext; + const storageContainer = createElement("div"); + sharedContext.activate = (vnode, container, anchor, namespace, optimized) => { + const instance2 = vnode.component; + move(vnode, container, anchor, 0, parentSuspense); + patch( + instance2.vnode, + vnode, + container, + anchor, + instance2, + parentSuspense, + namespace, + vnode.slotScopeIds, + optimized + ); + queuePostRenderEffect(() => { + instance2.isDeactivated = false; + if (instance2.a) { + invokeArrayFns(instance2.a); + } + const vnodeHook = vnode.props && vnode.props.onVnodeMounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance2.parent, vnode); + } + }, parentSuspense); + if (true) { + devtoolsComponentAdded(instance2); + } + }; + sharedContext.deactivate = (vnode) => { + const instance2 = vnode.component; + invalidateMount(instance2.m); + invalidateMount(instance2.a); + move(vnode, storageContainer, null, 1, parentSuspense); + queuePostRenderEffect(() => { + if (instance2.da) { + invokeArrayFns(instance2.da); + } + const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance2.parent, vnode); + } + instance2.isDeactivated = true; + }, parentSuspense); + if (true) { + devtoolsComponentAdded(instance2); + } + }; + function unmount(vnode) { + resetShapeFlag(vnode); + _unmount(vnode, instance, parentSuspense, true); + } + function pruneCache(filter) { + cache.forEach((vnode, key) => { + const name = getComponentName(vnode.type); + if (name && (!filter || !filter(name))) { + pruneCacheEntry(key); + } + }); + } + function pruneCacheEntry(key) { + const cached = cache.get(key); + if (cached && (!current || !isSameVNodeType(cached, current))) { + unmount(cached); + } else if (current) { + resetShapeFlag(current); + } + cache.delete(key); + keys.delete(key); + } + watch( + () => [props.include, props.exclude], + ([include, exclude]) => { + include && pruneCache((name) => matches(include, name)); + exclude && pruneCache((name) => !matches(exclude, name)); + }, + // prune post-render after `current` has been updated + { flush: "post", deep: true } + ); + let pendingCacheKey = null; + const cacheSubtree = () => { + if (pendingCacheKey != null) { + if (isSuspense(instance.subTree.type)) { + queuePostRenderEffect(() => { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + }, instance.subTree.suspense); + } else { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + } + } + }; + onMounted(cacheSubtree); + onUpdated(cacheSubtree); + onBeforeUnmount(() => { + cache.forEach((cached) => { + const { subTree, suspense } = instance; + const vnode = getInnerChild(subTree); + if (cached.type === vnode.type && cached.key === vnode.key) { + resetShapeFlag(vnode); + const da = vnode.component.da; + da && queuePostRenderEffect(da, suspense); + return; + } + unmount(cached); + }); + }); + return () => { + pendingCacheKey = null; + if (!slots.default) { + return null; + } + const children = slots.default(); + const rawVNode = children[0]; + if (children.length > 1) { + if (true) { + warn$1(`KeepAlive should contain exactly one component child.`); + } + current = null; + return children; + } else if (!isVNode(rawVNode) || !(rawVNode.shapeFlag & 4) && !(rawVNode.shapeFlag & 128)) { + current = null; + return rawVNode; + } + let vnode = getInnerChild(rawVNode); + if (vnode.type === Comment) { + current = null; + return vnode; + } + const comp = vnode.type; + const name = getComponentName( + isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp + ); + const { include, exclude, max } = props; + if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) { + current = vnode; + return rawVNode; + } + const key = vnode.key == null ? comp : vnode.key; + const cachedVNode = cache.get(key); + if (vnode.el) { + vnode = cloneVNode(vnode); + if (rawVNode.shapeFlag & 128) { + rawVNode.ssContent = vnode; + } + } + pendingCacheKey = key; + if (cachedVNode) { + vnode.el = cachedVNode.el; + vnode.component = cachedVNode.component; + if (vnode.transition) { + setTransitionHooks(vnode, vnode.transition); + } + vnode.shapeFlag |= 512; + keys.delete(key); + keys.add(key); + } else { + keys.add(key); + if (max && keys.size > parseInt(max, 10)) { + pruneCacheEntry(keys.values().next().value); + } + } + vnode.shapeFlag |= 256; + current = vnode; + return isSuspense(rawVNode.type) ? rawVNode : vnode; + }; + } +}; +var KeepAlive = KeepAliveImpl; +function matches(pattern, name) { + if (isArray(pattern)) { + return pattern.some((p2) => matches(p2, name)); + } else if (isString(pattern)) { + return pattern.split(",").includes(name); + } else if (isRegExp(pattern)) { + return pattern.test(name); + } + return false; +} +function onActivated(hook, target) { + registerKeepAliveHook(hook, "a", target); +} +function onDeactivated(hook, target) { + registerKeepAliveHook(hook, "da", target); +} +function registerKeepAliveHook(hook, type, target = currentInstance) { + const wrappedHook = hook.__wdc || (hook.__wdc = () => { + let current = target; + while (current) { + if (current.isDeactivated) { + return; + } + current = current.parent; + } + return hook(); + }); + injectHook(type, wrappedHook, target); + if (target) { + let current = target.parent; + while (current && current.parent) { + if (isKeepAlive(current.parent.vnode)) { + injectToKeepAliveRoot(wrappedHook, type, target, current); + } + current = current.parent; + } + } +} +function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { + const injected = injectHook( + type, + hook, + keepAliveRoot, + true + /* prepend */ + ); + onUnmounted(() => { + remove(keepAliveRoot[type], injected); + }, target); +} +function resetShapeFlag(vnode) { + vnode.shapeFlag &= ~256; + vnode.shapeFlag &= ~512; +} +function getInnerChild(vnode) { + return vnode.shapeFlag & 128 ? vnode.ssContent : vnode; +} +function injectHook(type, hook, target = currentInstance, prepend = false) { + if (target) { + const hooks = target[type] || (target[type] = []); + const wrappedHook = hook.__weh || (hook.__weh = (...args) => { + pauseTracking(); + const reset = setCurrentInstance(target); + const res = callWithAsyncErrorHandling(hook, target, type, args); + reset(); + resetTracking(); + return res; + }); + if (prepend) { + hooks.unshift(wrappedHook); + } else { + hooks.push(wrappedHook); + } + return wrappedHook; + } else if (true) { + const apiName = toHandlerKey(ErrorTypeStrings$1[type].replace(/ hook$/, "")); + warn$1( + `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.` + ); + } +} +var createHook = (lifecycle) => (hook, target = currentInstance) => { + if (!isInSSRComponentSetup || lifecycle === "sp") { + injectHook(lifecycle, (...args) => hook(...args), target); + } +}; +var onBeforeMount = createHook("bm"); +var onMounted = createHook("m"); +var onBeforeUpdate = createHook("bu"); +var onUpdated = createHook("u"); +var onBeforeUnmount = createHook("bum"); +var onUnmounted = createHook("um"); +var onServerPrefetch = createHook("sp"); +var onRenderTriggered = createHook( + "rtg" +); +var onRenderTracked = createHook( + "rtc" +); +function onErrorCaptured(hook, target = currentInstance) { + injectHook("ec", hook, target); +} +var COMPONENTS = "components"; +var DIRECTIVES = "directives"; +function resolveComponent(name, maybeSelfReference) { + return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; +} +var NULL_DYNAMIC_COMPONENT = Symbol.for("v-ndc"); +function resolveDynamicComponent(component) { + if (isString(component)) { + return resolveAsset(COMPONENTS, component, false) || component; + } else { + return component || NULL_DYNAMIC_COMPONENT; + } +} +function resolveDirective(name) { + return resolveAsset(DIRECTIVES, name); +} +function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { + const instance = currentRenderingInstance || currentInstance; + if (instance) { + const Component = instance.type; + if (type === COMPONENTS) { + const selfName = getComponentName( + Component, + false + ); + if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) { + return Component; + } + } + const res = ( + // local registration + // check instance[type] first which is resolved for options API + resolve(instance[type] || Component[type], name) || // global registration + resolve(instance.appContext[type], name) + ); + if (!res && maybeSelfReference) { + return Component; + } + if (warnMissing && !res) { + const extra = type === COMPONENTS ? ` +If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.` : ``; + warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`); + } + return res; + } else if (true) { + warn$1( + `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().` + ); + } +} +function resolve(registry, name) { + return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]); +} +function renderList(source, renderItem, cache, index) { + let ret; + const cached = cache && cache[index]; + if (isArray(source) || isString(source)) { + ret = new Array(source.length); + for (let i = 0, l = source.length; i < l; i++) { + ret[i] = renderItem(source[i], i, void 0, cached && cached[i]); + } + } else if (typeof source === "number") { + if (!Number.isInteger(source)) { + warn$1(`The v-for range expect an integer value but got ${source}.`); + } + ret = new Array(source); + for (let i = 0; i < source; i++) { + ret[i] = renderItem(i + 1, i, void 0, cached && cached[i]); + } + } else if (isObject(source)) { + if (source[Symbol.iterator]) { + ret = Array.from( + source, + (item, i) => renderItem(item, i, void 0, cached && cached[i]) + ); + } else { + const keys = Object.keys(source); + ret = new Array(keys.length); + for (let i = 0, l = keys.length; i < l; i++) { + const key = keys[i]; + ret[i] = renderItem(source[key], key, i, cached && cached[i]); + } + } + } else { + ret = []; + } + if (cache) { + cache[index] = ret; + } + return ret; +} +function createSlots(slots, dynamicSlots) { + for (let i = 0; i < dynamicSlots.length; i++) { + const slot = dynamicSlots[i]; + if (isArray(slot)) { + for (let j = 0; j < slot.length; j++) { + slots[slot[j].name] = slot[j].fn; + } + } else if (slot) { + slots[slot.name] = slot.key ? (...args) => { + const res = slot.fn(...args); + if (res) res.key = slot.key; + return res; + } : slot.fn; + } + } + return slots; +} +function renderSlot(slots, name, props = {}, fallback, noSlotted) { + if (currentRenderingInstance.isCE || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.isCE) { + if (name !== "default") props.name = name; + return createVNode("slot", props, fallback && fallback()); + } + let slot = slots[name]; + if (slot && slot.length > 1) { + warn$1( + `SSR-optimized slot function detected in a non-SSR-optimized render function. You need to mark this component with $dynamic-slots in the parent template.` + ); + slot = () => []; + } + if (slot && slot._c) { + slot._d = false; + } + openBlock(); + const validSlotContent = slot && ensureValidVNode(slot(props)); + const rendered = createBlock( + Fragment, + { + key: (props.key || // slot content array of a dynamic conditional slot may have a branch + // key attached in the `createSlots` helper, respect that + validSlotContent && validSlotContent.key || `_${name}`) + // #7256 force differentiate fallback content from actual content + (!validSlotContent && fallback ? "_fb" : "") + }, + validSlotContent || (fallback ? fallback() : []), + validSlotContent && slots._ === 1 ? 64 : -2 + ); + if (!noSlotted && rendered.scopeId) { + rendered.slotScopeIds = [rendered.scopeId + "-s"]; + } + if (slot && slot._c) { + slot._d = true; + } + return rendered; +} +function ensureValidVNode(vnodes) { + return vnodes.some((child) => { + if (!isVNode(child)) return true; + if (child.type === Comment) return false; + if (child.type === Fragment && !ensureValidVNode(child.children)) + return false; + return true; + }) ? vnodes : null; +} +function toHandlers(obj, preserveCaseIfNecessary) { + const ret = {}; + if (!isObject(obj)) { + warn$1(`v-on with no argument expects an object value.`); + return ret; + } + for (const key in obj) { + ret[preserveCaseIfNecessary && /[A-Z]/.test(key) ? `on:${key}` : toHandlerKey(key)] = obj[key]; + } + return ret; +} +var getPublicInstance = (i) => { + if (!i) return null; + if (isStatefulComponent(i)) return getComponentPublicInstance(i); + return getPublicInstance(i.parent); +}; +var publicPropertiesMap = ( + // Move PURE marker to new line to workaround compiler discarding it + // due to type annotation + extend(/* @__PURE__ */ Object.create(null), { + $: (i) => i, + $el: (i) => i.vnode.el, + $data: (i) => i.data, + $props: (i) => true ? shallowReadonly(i.props) : i.props, + $attrs: (i) => true ? shallowReadonly(i.attrs) : i.attrs, + $slots: (i) => true ? shallowReadonly(i.slots) : i.slots, + $refs: (i) => true ? shallowReadonly(i.refs) : i.refs, + $parent: (i) => getPublicInstance(i.parent), + $root: (i) => getPublicInstance(i.root), + $emit: (i) => i.emit, + $options: (i) => __VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type, + $forceUpdate: (i) => i.f || (i.f = () => { + i.effect.dirty = true; + queueJob(i.update); + }), + $nextTick: (i) => i.n || (i.n = nextTick.bind(i.proxy)), + $watch: (i) => __VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP + }) +); +var isReservedPrefix = (key) => key === "_" || key === "$"; +var hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key); +var PublicInstanceProxyHandlers = { + get({ _: instance }, key) { + if (key === "__v_skip") { + return true; + } + const { ctx, setupState, data, props, accessCache, type, appContext } = instance; + if (key === "__isVue") { + return true; + } + let normalizedProps; + if (key[0] !== "$") { + const n = accessCache[key]; + if (n !== void 0) { + switch (n) { + case 1: + return setupState[key]; + case 2: + return data[key]; + case 4: + return ctx[key]; + case 3: + return props[key]; + } + } else if (hasSetupBinding(setupState, key)) { + accessCache[key] = 1; + return setupState[key]; + } else if (data !== EMPTY_OBJ && hasOwn(data, key)) { + accessCache[key] = 2; + return data[key]; + } else if ( + // only cache other properties when instance has declared (thus stable) + // props + (normalizedProps = instance.propsOptions[0]) && hasOwn(normalizedProps, key) + ) { + accessCache[key] = 3; + return props[key]; + } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { + accessCache[key] = 4; + return ctx[key]; + } else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) { + accessCache[key] = 0; + } + } + const publicGetter = publicPropertiesMap[key]; + let cssModule, globalProperties; + if (publicGetter) { + if (key === "$attrs") { + track(instance.attrs, "get", ""); + markAttrsAccessed(); + } else if (key === "$slots") { + track(instance, "get", key); + } + return publicGetter(instance); + } else if ( + // css module (injected by vue-loader) + (cssModule = type.__cssModules) && (cssModule = cssModule[key]) + ) { + return cssModule; + } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { + accessCache[key] = 4; + return ctx[key]; + } else if ( + // global properties + globalProperties = appContext.config.globalProperties, hasOwn(globalProperties, key) + ) { + { + return globalProperties[key]; + } + } else if (currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading + // to infinite warning loop + key.indexOf("__v") !== 0)) { + if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) { + warn$1( + `Property ${JSON.stringify( + key + )} must be accessed via $data because it starts with a reserved character ("$" or "_") and is not proxied on the render context.` + ); + } else if (instance === currentRenderingInstance) { + warn$1( + `Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.` + ); + } + } + }, + set({ _: instance }, key, value) { + const { data, setupState, ctx } = instance; + if (hasSetupBinding(setupState, key)) { + setupState[key] = value; + return true; + } else if (setupState.__isScriptSetup && hasOwn(setupState, key)) { + warn$1(`Cannot mutate + + \ No newline at end of file diff --git a/.vitepress/theme/components/Todo.vue b/.vitepress/theme/components/Todo.vue new file mode 100644 index 0000000000..9b64ed984c --- /dev/null +++ b/.vitepress/theme/components/Todo.vue @@ -0,0 +1,325 @@ + + + + + \ No newline at end of file diff --git a/.vitepress/theme/components/TodoItem.vue b/.vitepress/theme/components/TodoItem.vue new file mode 100644 index 0000000000..971fb4eb15 --- /dev/null +++ b/.vitepress/theme/components/TodoItem.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/.vitepress/theme/components/TodoList.vue b/.vitepress/theme/components/TodoList.vue new file mode 100644 index 0000000000..6f7bc3fc6e --- /dev/null +++ b/.vitepress/theme/components/TodoList.vue @@ -0,0 +1,46 @@ + + + + + \ No newline at end of file diff --git a/.vitepress/theme/components/Trippin.vue b/.vitepress/theme/components/Trippin.vue new file mode 100644 index 0000000000..9d270fd295 --- /dev/null +++ b/.vitepress/theme/components/Trippin.vue @@ -0,0 +1,137 @@ + + + \ No newline at end of file diff --git a/.vitepress/theme/custom.css b/.vitepress/theme/custom.css new file mode 100644 index 0000000000..4673825cc6 --- /dev/null +++ b/.vitepress/theme/custom.css @@ -0,0 +1,317 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + /** + * Colors + * -------------------------------------------------------------------------- */ + :root { + /* Fire */ + --ui5-fire-main: #ff5a37; /* outrageous-orange-400 */ + --ui5-fire-secondary: #ffa42c; /* sunshade-400 */ + --ui5-fire-background: #000000; /* black */ + + /* Water */ + --ui5-water-main: #1873b4; /* denim-600 */ + --ui5-water-secondary: #53b8de; /* viking-400 */ + --ui5-water-background: #ffffff; /* white */ + + --vp-home-hero-image-background-image: linear-gradient(90deg, rgba(255,255,255,0.5) 0%, rgba(83,184,222,0.5) 35%, rgba(0,212,255,0.5) 100%); + --vp-home-hero-image-filter: blur(40px); + --vp-home-hero-name-color: #1873b4; + --vp-c-brand-2: #53b8de; /* lochmara-500 */ + /* The color for solid background, such as bg color of the button. */ + --vp-c-brand-3: #1873b4; /* endeavour-700 */ + } + .dark { --vp-home-hero-image-background-image: linear-gradient(90deg, rgba(255,90,55,0.5) 0%, rgba(255,164,44,0.5) 35%, rgba(56, 60, 61,0.5) 100%); + --vp-home-hero-name-color: #ff5a37; + } + @media (min-width: 640px) { :root { --vp-home-hero-image-filter: blur(56px); } } + @media (min-width: 960px) { :root { --vp-home-hero-image-filter: blur(72px); } } + .VPFeature .icon { background-color: transparent; + /* Tailwind CSS Color Generator + ** https://uicolors.app/create + */ + + /* VP */ + /* The most solid color used mainly for colored text. */ + --vp-c-brand-1: #1873b4; /* lochmara-600 */ + /* The color used mainly for hover state of the button. */ + + /* The color used for subtle background such as custom container or badges. */ + /* The soft color must be semi transparent alpha channel. */ + /*--vp-c-brand-soft: rgba(12, 72, 120, 0.14);*/ /* --brand-dark-blue */ + --vp-c-brand-soft: rgba(3, 103, 161, 0.14); /* lochmara-700 */ + + + + } + .dark { + /* The most solid color used mainly for colored text. */ + --vp-c-brand-1: #ff5a37; /* lochmara-600 */ + /* The color used mainly for hover state of the button. */ + --vp-c-brand-2: #ffa42c; /* lochmara-500 */ + /* The color for solid background, such as bg color of the button. */ + --vp-c-brand-3: #ff5a37; /* endeavour-700 */ + + /* The bg color used for main screen */ + --vp-c-bg: #000000; + /* The alternative bg color used in places such as "sidebar" or "code block". */ + + /* The elevated bg color. This is used at parts where it "floats", such as "dialog". */ + /*--vp-c-bg-elv: red;*/ /* #1d2025;*/ + /* The bg color to slightly ditinguish some components from the page. + ** Used for things like "carbon ads" or "table". + */ + --vp-c-bg-soft: #2b313a; /* 202127 */ + /* This is used for separators. This is used to divide sections within the same components, + ** such as having separator on "h2" heading. + */ + --vp-c-divider: rgba(82,82,89,0.32); /*#2e2e32;*/ + /* This is designed for borders on interactive components. + ** For example this should be used for a button outline. */ + /*--vp-c-border: #3c3f44; */ + /* This is used to divide components in the page. For example the header and the rest of the page. */ + /*--vp-c-gutter: var(--vp-c-bg-alt);*/ /* #000000 */ + --vp-c-gutter: transparent; /* #000000 */ + } + + img { + @apply rounded-md; + } + + /* fix Tailwind default issue for Search button */ + .DocSearch.button, + .DocSearch[type="button"] { + background-color: var(--vp-c-bg-alt); + } +} + +/* Implement udina design language by avoiding repeated utility patterns */ +@layer components { + /* reset vpdoc */ + .vp-doc .u-list-reset { + @apply list-none list-image-none p-0 m-0; + } + + .vp-doc .u-list-reset li + li { + @apply mt-0; + } + + /* Default KBD + ** https://flowbite.com/docs/components/kbd/ + */ + .u-kbd { + @apply px-2 py-1 text-xs font-semibold text-gray-800 bg-gray-50 border border-gray-300 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500; + } + + /* udina design language */ + .udina { + @apply font-sans font-extrabold; + } + + .u-right-brand { + @apply float-right ml-4 w-12 md:ml-8 md:w-20 lg:w-24; + } + + .u-p-white { + @apply p-2 bg-white; + } + + .u-bar { + @apply flex flex-col md:flex-row md:justify-between md:items-center space-y-2 md:space-y-0; + } + + .u-bar-content { + @apply flex items-center; + } + + .u-bar-singleLineContent { + @apply flex md:items-center flex-col md:flex-row space-y-2 md:space-y-0; + } +} + +/** + * Prototypes + * -------------------------------------------------------------------------- */ + +/* disable anchor undeline */ +.vp-doc a { + text-decoration: none; +} + +.u-pi { + color: transparent; + font-size: 1rem; + transition: all .2s ease-in-out; +} + +.u-pi:hover { + font-size: 2rem; + color: inherit; +} + +/** +* Custom Block +* -------------------------------------------------------------------------- */ +.vp-doc .custom-block { + padding: 16px; +} + +.vp-doc .custom-block.tip { + border-color: var(--vp-c-tip-1); +} + +.vp-doc .custom-block.warning { + border-color: var(--vp-c-warning-1); +} + +.vp-doc .custom-block.danger { + border-color: var(--vp-c-danger-1); +} + +.vp-doc .custom-block:not(.info) { + /*font-size: 95%;*/ + border-width: 0 0 0 7px; +} + +/* allow blue/udina color links in blocks */ +.vp-doc .custom-block a { + color: var(--vp-c-brand); +} + +/* clearfix to avoid overlapping float-right image inside custom block */ +.vp-doc .custom-block:after { + content: ""; + display: table; + clear: both; +} + +/** +* zoom vanilla +* -------------------------------------------------------------------------- */ +img[data-action="zoom"] { + cursor: zoom-in; +} + +.zoom-img, +.zoom-img-wrap { + position: relative; + z-index: 666; + /*z-index: 20;*/ + transition: all 300ms; +} + +img.zoom-img { + cursor: zoom-out; + /* UDINA */ + /*z-index: 21;*/ + /* reset u-right-brand margin-left */ + margin: 0; +} + +.zoom-overlay { + cursor: zoom-out; + z-index: 420; + background: #fff; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + filter: "alpha(opacity=0)"; + opacity: 0; + transition: opacity 300ms; + /* UDINA */ + background-color: var(--vp-c-bg); +} + +.zoom-overlay-open .zoom-overlay { + filter: "alpha(opacity=100)"; + opacity: 1; +} + +/** +* Blockquotes +* -------------------------------------------------------------------------- */ +.udina-quote { + font-family: Georgia, Times, "Times New Roman", serif; + font-size: 1.25em; + font-style: italic; + position: relative; + z-index: 0; +} + +.udina-quote:before { + content: ""; + position: absolute; + top: 50%; + left: -4px; + height: 1em; + background-color: var(--c-bg); + width: 5px; + margin-top: -0.5em; +} + +.udina-quote:after { + content: "“"; + position: absolute; + top: 50%; + left: -0.5em; + color: var(--c-border-dark); + font-size: 2em; + line-height: 2em; + text-align: center; + text-indent: -2px; + width: 0.8em; + margin-top: -0.75em; +} + +.udina-quote cite { + display: block; + font-size: 0.75em; + margin-top: 0.5em; +} + +/** +* Figure (used by markdown-it-figure) +* -------------------------------------------------------------------------- */ +figure { + margin-inline-start: 0; + margin-inline-end: 0; + text-align: center; + text-align: -webkit-center; + margin: 1rem 0; +} + +figcaption { + margin-top: 0.5rem; + font-style: italic; + font-size: small; + text-align: center; + text-align: -webkit-center; +} + +/** +* Learn more +* -------------------------------------------------------------------------- */ +.learn-more { + font-style: italic; + margin-top: -5px; + margin-bottom: 5px; + display: block; +} + +li .learn-more { + margin-top: 0; +} + +.learn-more:before { + content: url(/learn-more.svg); + display: inline-block; + width: 20px; + height: 20px; + margin-right: 5px; + vertical-align: middle; +} diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts new file mode 100644 index 0000000000..82c2a17338 --- /dev/null +++ b/.vitepress/theme/index.ts @@ -0,0 +1,52 @@ +import DefaultTheme from "vitepress/theme"; +import { EnhanceAppContext } from 'vitepress/dist/client/index.js' +import { useRoute } from "vitepress"; +import { onMounted, watch, nextTick } from "vue"; + +// custom css +import "./custom.css"; + +// global components +import Badgen from "@theme/components/Badgen.vue"; + +export default { + ...DefaultTheme, + + enhanceApp(ctx: EnhanceAppContext) { + // app is the Vue 3 app instance from `createApp()`. + // router is VitePress' custom router. `siteData` is + // a `ref` of current site-level metadata. + + // extend default theme custom behaviour. + DefaultTheme.enhanceApp(ctx); + + // register your custom global components + ctx.app.component("Badgen", Badgen); + }, + + setup() { + // this function will be executed inside VitePressApp's setup hook. + // all composition APIs are available here. + const route = useRoute(); + let initZoom: () => void; + + onMounted(async () => { + // initialize components based on data attribute selectors + //initCarousels(); + + (await import("./mixins/u-zoom-vanilla.js")).default; + initZoom = () => { + // no zoom inside links or disabled by class=".no-zoom" + document.querySelectorAll(".main img:not(a>img):not(.no-zoom)").forEach(el => { + el.setAttribute("data-action", "zoom"); + }); + }; + + initZoom(); + }); + watch( + () => route.path, + () => nextTick(() => initZoom()) + ); + }, +}; diff --git a/.vitepress/theme/loaders/trippin.data.js b/.vitepress/theme/loaders/trippin.data.js new file mode 100644 index 0000000000..14ab54779e --- /dev/null +++ b/.vitepress/theme/loaders/trippin.data.js @@ -0,0 +1,7 @@ +export default { + async load() { + // fetch remote data + const service = 'https://services.odata.org/Trippin_Staging/(S(iw1anra4xygjyssbeef0yeyy))' + return (await fetch(`${service}/People?$select=FirstName,LastName,UserName&$orderBy=LastName,FirstName&$top=100`)).json() + } +} \ No newline at end of file diff --git a/.vitepress/theme/mixins/UI5WebComponentsMixin.js b/.vitepress/theme/mixins/UI5WebComponentsMixin.js new file mode 100644 index 0000000000..6db233c800 --- /dev/null +++ b/.vitepress/theme/mixins/UI5WebComponentsMixin.js @@ -0,0 +1,41 @@ +import { setTheme } from "@ui5/webcomponents-base/dist/config/Theme.js"; + +// import dark theme assets +import "@ui5/webcomponents/dist/Assets.js"; +//import "@ui5/webcomponents-fiori/dist/Assets.js"; + +export default { + mounted() { + // theme handler + this.mutationTarget = document.querySelector("html"); + + // initially apply theme depending on darkMode + this.onClassChange(this.mutationTarget.classList.value); + + // observe html class list + this.observer = new MutationObserver((mutations) => { + for (const m of mutations) { + const newValue = m.target.getAttribute(m.attributeName); + this.$nextTick(() => { + this.onClassChange(newValue); + }); + } + }); + + // observe html class list + this.observer.observe(this.mutationTarget, { + attributes: true, + attributeFilter: ["class"], + }); + }, + beforeDestroy() { + this.observer.disconnect(); + }, + methods: { + onClassChange: function (classAttrValue) { + const classList = classAttrValue.split(" "); + + setTheme(classList.includes("dark") ? "sap_horizon_dark" : "sap_horizon"); + }, + }, +}; diff --git a/.vitepress/theme/mixins/u-zoom-vanilla.js b/.vitepress/theme/mixins/u-zoom-vanilla.js new file mode 100644 index 0000000000..b8a9493e83 --- /dev/null +++ b/.vitepress/theme/mixins/u-zoom-vanilla.js @@ -0,0 +1,265 @@ +export default +function () { + "use strict"; + var OFFSET = 80 + + // From http://youmightnotneedjquery.com/#offset + function offset(element) { + var rect = element.getBoundingClientRect() + var scrollTop = window.pageYOffset || + document.documentElement.scrollTop || + document.body.scrollTop || + 0 + var scrollLeft = window.pageXOffset || + document.documentElement.scrollLeft || + document.body.scrollLeft || + 0 + return { + top: rect.top + scrollTop, + left: rect.left + scrollLeft + } + } + + function zoomListener() { + var activeZoom = null + var initialScrollPosition = null + var initialTouchPosition = null + + function listen() { + document.body.addEventListener('click', function (event) { + if (event.target.getAttribute('data-action') !== 'zoom' || + event.target.tagName !== 'IMG') return + + zoom(event) + }) + } + + function zoom(event) { + event.stopPropagation() + + if (document.body.classList.contains('zoom-overlay-open')) return + + if (event.metaKey || event.ctrlKey) return openInNewWindow() + + closeActiveZoom({ forceDispose: true }) + + activeZoom = vanillaZoom(event.target) + activeZoom.zoomImage() + + addCloseActiveZoomListeners() + } + + function openInNewWindow() { + window.open(event.target.getAttribute('data-original') || + event.target.currentSrc || + event.target.src, + '_blank') + } + + function closeActiveZoom(options) { + options = options || { forceDispose: false } + if (!activeZoom) return + + activeZoom[options.forceDispose ? 'dispose' : 'close']() + removeCloseActiveZoomListeners() + activeZoom = null + } + + function addCloseActiveZoomListeners() { + // todo(fat): probably worth throttling this + window.addEventListener('scroll', handleScroll) + document.addEventListener('click', handleClick) + document.addEventListener('keyup', handleEscPressed) + document.addEventListener('touchstart', handleTouchStart) + document.addEventListener('touchend', handleClick) + } + + function removeCloseActiveZoomListeners() { + window.removeEventListener('scroll', handleScroll) + document.removeEventListener('keyup', handleEscPressed) + document.removeEventListener('click', handleClick) + document.removeEventListener('touchstart', handleTouchStart) + document.removeEventListener('touchend', handleClick) + } + + function handleScroll(event) { + if (initialScrollPosition === null) initialScrollPosition = window.pageYOffset + var deltaY = initialScrollPosition - window.pageYOffset + if (Math.abs(deltaY) >= 40) closeActiveZoom() + } + + function handleEscPressed(event) { + if (event.keyCode == 27) closeActiveZoom() + } + + function handleClick(event) { + event.stopPropagation() + event.preventDefault() + closeActiveZoom() + } + + function handleTouchStart(event) { + initialTouchPosition = event.touches[0].pageY + event.target.addEventListener('touchmove', handleTouchMove) + } + + function handleTouchMove(event) { + if (Math.abs(event.touches[0].pageY - initialTouchPosition) <= 10) return + closeActiveZoom() + event.target.removeEventListener('touchmove', handleTouchMove) + } + + return { listen: listen } + } + + var vanillaZoom = (function () { + var fullHeight = null + var fullWidth = null + var overlay = null + var imgScaleFactor = null + + var targetImage = null + var targetImageWrap = null + var targetImageClone = null + + function zoomImage() { + var img = document.createElement('img') + img.onload = function () { + fullHeight = Number(img.height) + fullWidth = Number(img.width) + zoomOriginal() + } + img.src = targetImage.currentSrc || targetImage.src + } + + function zoomOriginal() { + targetImageWrap = document.createElement('div') + targetImageWrap.className = 'zoom-img-wrap' + targetImageWrap.style.position = 'absolute' + targetImageWrap.style.top = offset(targetImage).top + 'px' + targetImageWrap.style.left = offset(targetImage).left + 'px' + + targetImageClone = targetImage.cloneNode() + targetImageClone.style.visibility = 'hidden' + + targetImage.style.width = targetImage.offsetWidth + 'px' + targetImage.parentNode.replaceChild(targetImageClone, targetImage) + + document.body.appendChild(targetImageWrap) + targetImageWrap.appendChild(targetImage) + + targetImage.classList.add('zoom-img') + targetImage.setAttribute('data-action', 'zoom-out') + + overlay = document.createElement('div') + overlay.className = 'zoom-overlay' + + document.body.appendChild(overlay) + + calculateZoom() + triggerAnimation() + } + + function calculateZoom() { + // UDINA + var maxWidth = window.innerWidth * 0.8 + var ratio = targetImage.width / targetImage.height + var isSVG = targetImage?.src?.endsWith(".svg") + + targetImage.offsetWidth // repaint before animating + + //var originalFullImageWidth = fullWidth + var originalFullImageWidth = (isSVG) ? maxWidth : fullWidth + //var originalFullImageHeight = fullHeight + var originalFullImageHeight = (isSVG) ? maxWidth / ratio : fullHeight + + var maxScaleFactor = originalFullImageWidth / targetImage.width + //var maxScaleFactor = originalFullImageWidth / originalFullImageHeight + + var viewportHeight = window.innerHeight - OFFSET + var viewportWidth = window.innerWidth - OFFSET + + var imageAspectRatio = originalFullImageWidth / originalFullImageHeight + var viewportAspectRatio = viewportWidth / viewportHeight + + if (originalFullImageWidth < viewportWidth && originalFullImageHeight < viewportHeight) { + imgScaleFactor = maxScaleFactor + } else if (imageAspectRatio < viewportAspectRatio) { + imgScaleFactor = (viewportHeight / originalFullImageHeight) * maxScaleFactor + } else { + imgScaleFactor = (viewportWidth / originalFullImageWidth) * maxScaleFactor + } + } + + function triggerAnimation() { + targetImage.offsetWidth // repaint before animating + + var imageOffset = offset(targetImage) + var scrollTop = window.pageYOffset + + var viewportY = scrollTop + (window.innerHeight / 2) + var viewportX = (window.innerWidth / 2) + + var imageCenterY = imageOffset.top + (targetImage.height / 2) + var imageCenterX = imageOffset.left + (targetImage.width / 2) + + var translateY = Math.round(viewportY - imageCenterY) + var translateX = Math.round(viewportX - imageCenterX) + + var targetImageTransform = 'scale(' + imgScaleFactor + ')' + var targetImageWrapTransform = + 'translate(' + translateX + 'px, ' + translateY + 'px) translateZ(0)' + + targetImage.style.webkitTransform = targetImageTransform + targetImage.style.msTransform = targetImageTransform + targetImage.style.transform = targetImageTransform + + targetImageWrap.style.webkitTransform = targetImageWrapTransform + targetImageWrap.style.msTransform = targetImageWrapTransform + targetImageWrap.style.transform = targetImageWrapTransform + + document.body.classList.add('zoom-overlay-open') + } + + function close() { + document.body.classList.remove('zoom-overlay-open') + document.body.classList.add('zoom-overlay-transitioning') + + targetImage.style.webkitTransform = '' + targetImage.style.msTransform = '' + targetImage.style.transform = '' + + targetImageWrap.style.webkitTransform = '' + targetImageWrap.style.msTransform = '' + targetImageWrap.style.transform = '' + + if (!'transition' in document.body.style) return dispose() + + targetImageWrap.addEventListener('transitionend', dispose) + targetImageWrap.addEventListener('webkitTransitionEnd', dispose) + } + + function dispose() { + targetImage.removeEventListener('transitionend', dispose) + targetImage.removeEventListener('webkitTransitionEnd', dispose) + + if (!targetImageWrap || !targetImageWrap.parentNode) return + + targetImage.classList.remove('zoom-img') + targetImage.style.width = '' + targetImage.setAttribute('data-action', 'zoom') + + targetImageClone.parentNode.replaceChild(targetImage, targetImageClone) + targetImageWrap.parentNode.removeChild(targetImageWrap) + overlay.parentNode.removeChild(overlay) + + document.body.classList.remove('zoom-overlay-transitioning') + } + + return function (target) { + targetImage = target + return { zoomImage: zoomImage, close: close, dispose: dispose } + } + }()) + + zoomListener().listen() +}() \ No newline at end of file diff --git a/.vitepress/theme/model/trippin/QTrippin.d.ts b/.vitepress/theme/model/trippin/QTrippin.d.ts new file mode 100644 index 0000000000..c32bc960c7 --- /dev/null +++ b/.vitepress/theme/model/trippin/QTrippin.d.ts @@ -0,0 +1,160 @@ +import { QStringPath, QEnumPath, QNumberPath, QCollectionPath, QStringCollection, QEntityCollectionPath, QEntityPath, QEnumCollection, QId, QStringParam, QFunction, QAction, QNumberParam, QGuidPath, QDateTimeOffsetPath, QueryObject } from "@odata2ts/odata-query-objects"; +import { PersonId, Person_GetFriendsTripsParams, Person_UpdateLastNameParams, Person_ShareTripParams, AirlineId, AirportId, TripId, PlanItemId, GetNearestAirportParams } from "./TrippinModel"; +export declare class QPerson extends QueryObject { + readonly userName: QStringPath; + readonly firstName: QStringPath; + readonly lastName: QStringPath; + readonly middleName: QStringPath; + readonly gender: QEnumPath; + readonly age: QNumberPath; + readonly emails: QCollectionPath; + readonly addressInfo: QEntityCollectionPath; + readonly homeAddress: QEntityPath; + readonly favoriteFeature: QEnumPath; + readonly features: QCollectionPath; + readonly friends: QEntityCollectionPath; + readonly bestFriend: QEntityPath; + readonly trips: QEntityCollectionPath; +} +export declare const qPerson: QPerson; +export declare class QPersonId extends QId { + private readonly params; + getParams(): QStringParam[]; +} +export declare class Person_QGetFavoriteAirline extends QFunction { + private readonly params; + constructor(); + getParams(): []; + buildUrl(): string; +} +export declare class Person_QGetFriendsTrips extends QFunction { + private readonly params; + constructor(); + getParams(): QStringParam[]; +} +export declare class Person_QUpdateLastName extends QAction { + private readonly params; + constructor(); + getParams(): QStringParam[]; +} +export declare class Person_QShareTrip extends QAction { + private readonly params; + constructor(); + getParams(): (QStringParam | QNumberParam)[]; +} +export declare class QAirline extends QueryObject { + readonly airlineCode: QStringPath; + readonly name: QStringPath; +} +export declare const qAirline: QAirline; +export declare class QAirlineId extends QId { + private readonly params; + getParams(): QStringParam[]; +} +export declare class QAirport extends QueryObject { + readonly name: QStringPath; + readonly icaoCode: QStringPath; + readonly iataCode: QStringPath; + readonly location: QEntityPath; +} +export declare const qAirport: QAirport; +export declare class QAirportId extends QId { + private readonly params; + getParams(): QStringParam[]; +} +export declare class QTrip extends QueryObject { + readonly tripId: QNumberPath; + readonly shareId: QGuidPath; + readonly name: QStringPath; + readonly budget: QNumberPath; + readonly description: QStringPath; + readonly tags: QCollectionPath; + readonly startsAt: QDateTimeOffsetPath; + readonly endsAt: QDateTimeOffsetPath; + readonly planItems: QEntityCollectionPath; +} +export declare const qTrip: QTrip; +export declare class QTripId extends QId { + private readonly params; + getParams(): QNumberParam[]; +} +export declare class Trip_QGetInvolvedPeople extends QFunction { + private readonly params; + constructor(); + getParams(): []; + buildUrl(): string; +} +export declare class QPlanItem extends QueryObject { + readonly planItemId: QNumberPath; + readonly confirmationCode: QStringPath; + readonly startsAt: QDateTimeOffsetPath; + readonly endsAt: QDateTimeOffsetPath; + readonly duration: QStringPath; +} +export declare const qPlanItem: QPlanItem; +export declare class QPlanItemId extends QId { + private readonly params; + getParams(): QNumberParam[]; +} +export declare class QEvent extends QPlanItem { + readonly occursAt: QEntityPath; + readonly description: QStringPath; +} +export declare const qEvent: QEvent; +export declare class QPublicTransportation extends QPlanItem { + readonly seatNumber: QStringPath; +} +export declare const qPublicTransportation: QPublicTransportation; +export declare class QFlight extends QPublicTransportation { + readonly flightNumber: QStringPath; + readonly airline: QEntityPath; + readonly from: QEntityPath; + readonly to: QEntityPath; +} +export declare const qFlight: QFlight; +export declare class QEmployee extends QPerson { + readonly cost: QNumberPath; + readonly peers: QEntityCollectionPath; +} +export declare const qEmployee: QEmployee; +export declare class QManager extends QPerson { + readonly budget: QNumberPath; + readonly bossOffice: QEntityPath; + readonly directReports: QEntityCollectionPath; +} +export declare const qManager: QManager; +export declare class QLocation extends QueryObject { + readonly address: QStringPath; + readonly city: QEntityPath; +} +export declare const qLocation: QLocation; +export declare class QCity extends QueryObject { + readonly name: QStringPath; + readonly countryRegion: QStringPath; + readonly region: QStringPath; +} +export declare const qCity: QCity; +export declare class QAirportLocation extends QLocation { + readonly loc: QStringPath; +} +export declare const qAirportLocation: QAirportLocation; +export declare class QEventLocation extends QLocation { + readonly buildingInfo: QStringPath; +} +export declare const qEventLocation: QEventLocation; +export declare class QGetPersonWithMostFriends extends QFunction { + private readonly params; + constructor(); + getParams(): []; + buildUrl(): string; +} +export declare class QGetNearestAirport extends QFunction { + private readonly params; + constructor(); + getParams(): QNumberParam[]; +} +export declare class QResetDataSource extends QAction { + private readonly params; + constructor(); + getParams(): []; +} diff --git a/.vitepress/theme/model/trippin/QTrippin.js b/.vitepress/theme/model/trippin/QTrippin.js new file mode 100644 index 0000000000..934ac615d4 --- /dev/null +++ b/.vitepress/theme/model/trippin/QTrippin.js @@ -0,0 +1,207 @@ +import { QStringPath, QEnumPath, QNumberPath, QCollectionPath, QStringCollection, QEntityCollectionPath, QEntityPath, QEnumCollection, QId, QStringParam, QFunction, OperationReturnType, ReturnTypes, QComplexParam, QAction, QNumberParam, QGuidPath, QDateTimeOffsetPath, QueryObject } from "@odata2ts/odata-query-objects"; +export class QPerson extends QueryObject { + userName = new QStringPath(this.withPrefix("UserName")); + firstName = new QStringPath(this.withPrefix("FirstName")); + lastName = new QStringPath(this.withPrefix("LastName")); + middleName = new QStringPath(this.withPrefix("MiddleName")); + gender = new QEnumPath(this.withPrefix("Gender")); + age = new QNumberPath(this.withPrefix("Age")); + emails = new QCollectionPath(this.withPrefix("Emails"), () => QStringCollection); + addressInfo = new QEntityCollectionPath(this.withPrefix("AddressInfo"), () => QLocation); + homeAddress = new QEntityPath(this.withPrefix("HomeAddress"), () => QLocation); + favoriteFeature = new QEnumPath(this.withPrefix("FavoriteFeature")); + features = new QCollectionPath(this.withPrefix("Features"), () => QEnumCollection); + friends = new QEntityCollectionPath(this.withPrefix("Friends"), () => QPerson); + bestFriend = new QEntityPath(this.withPrefix("BestFriend"), () => QPerson); + trips = new QEntityCollectionPath(this.withPrefix("Trips"), () => QTrip); +} +export const qPerson = new QPerson(); +export class QPersonId extends QId { + params = [new QStringParam("UserName", "userName")]; + getParams() { + return this.params; + } +} +export class Person_QGetFavoriteAirline extends QFunction { + params = []; + constructor() { + super("Trippin.GetFavoriteAirline", new OperationReturnType(ReturnTypes.COMPLEX, new QComplexParam("NONE", new QAirline))); + } + getParams() { + return this.params; + } + buildUrl() { + return super.buildUrl(undefined); + } +} +export class Person_QGetFriendsTrips extends QFunction { + params = [new QStringParam("userName")]; + constructor() { + super("Trippin.GetFriendsTrips", new OperationReturnType(ReturnTypes.COMPLEX_COLLECTION, new QComplexParam("NONE", new QTrip))); + } + getParams() { + return this.params; + } +} +export class Person_QUpdateLastName extends QAction { + params = [new QStringParam("lastName")]; + constructor() { + super("Trippin.UpdateLastName"); + } + getParams() { + return this.params; + } +} +export class Person_QShareTrip extends QAction { + params = [new QStringParam("userName"), new QNumberParam("tripId")]; + constructor() { + super("Trippin.ShareTrip"); + } + getParams() { + return this.params; + } +} +export class QAirline extends QueryObject { + airlineCode = new QStringPath(this.withPrefix("AirlineCode")); + name = new QStringPath(this.withPrefix("Name")); +} +export const qAirline = new QAirline(); +export class QAirlineId extends QId { + params = [new QStringParam("AirlineCode", "airlineCode")]; + getParams() { + return this.params; + } +} +export class QAirport extends QueryObject { + name = new QStringPath(this.withPrefix("Name")); + icaoCode = new QStringPath(this.withPrefix("IcaoCode")); + iataCode = new QStringPath(this.withPrefix("IataCode")); + location = new QEntityPath(this.withPrefix("Location"), () => QAirportLocation); +} +export const qAirport = new QAirport(); +export class QAirportId extends QId { + params = [new QStringParam("IcaoCode", "icaoCode")]; + getParams() { + return this.params; + } +} +export class QTrip extends QueryObject { + tripId = new QNumberPath(this.withPrefix("TripId")); + shareId = new QGuidPath(this.withPrefix("ShareId")); + name = new QStringPath(this.withPrefix("Name")); + budget = new QNumberPath(this.withPrefix("Budget")); + description = new QStringPath(this.withPrefix("Description")); + tags = new QCollectionPath(this.withPrefix("Tags"), () => QStringCollection); + startsAt = new QDateTimeOffsetPath(this.withPrefix("StartsAt")); + endsAt = new QDateTimeOffsetPath(this.withPrefix("EndsAt")); + planItems = new QEntityCollectionPath(this.withPrefix("PlanItems"), () => QPlanItem); +} +export const qTrip = new QTrip(); +export class QTripId extends QId { + params = [new QNumberParam("TripId", "tripId")]; + getParams() { + return this.params; + } +} +export class Trip_QGetInvolvedPeople extends QFunction { + params = []; + constructor() { + super("Trippin.GetInvolvedPeople", new OperationReturnType(ReturnTypes.COMPLEX_COLLECTION, new QComplexParam("NONE", new QPerson))); + } + getParams() { + return this.params; + } + buildUrl() { + return super.buildUrl(undefined); + } +} +export class QPlanItem extends QueryObject { + planItemId = new QNumberPath(this.withPrefix("PlanItemId")); + confirmationCode = new QStringPath(this.withPrefix("ConfirmationCode")); + startsAt = new QDateTimeOffsetPath(this.withPrefix("StartsAt")); + endsAt = new QDateTimeOffsetPath(this.withPrefix("EndsAt")); + duration = new QStringPath(this.withPrefix("Duration")); +} +export const qPlanItem = new QPlanItem(); +export class QPlanItemId extends QId { + params = [new QNumberParam("PlanItemId", "planItemId")]; + getParams() { + return this.params; + } +} +export class QEvent extends QPlanItem { + occursAt = new QEntityPath(this.withPrefix("OccursAt"), () => QEventLocation); + description = new QStringPath(this.withPrefix("Description")); +} +export const qEvent = new QEvent(); +export class QPublicTransportation extends QPlanItem { + seatNumber = new QStringPath(this.withPrefix("SeatNumber")); +} +export const qPublicTransportation = new QPublicTransportation(); +export class QFlight extends QPublicTransportation { + flightNumber = new QStringPath(this.withPrefix("FlightNumber")); + airline = new QEntityPath(this.withPrefix("Airline"), () => QAirline); + from = new QEntityPath(this.withPrefix("From"), () => QAirport); + to = new QEntityPath(this.withPrefix("To"), () => QAirport); +} +export const qFlight = new QFlight(); +export class QEmployee extends QPerson { + cost = new QNumberPath(this.withPrefix("Cost")); + peers = new QEntityCollectionPath(this.withPrefix("Peers"), () => QPerson); +} +export const qEmployee = new QEmployee(); +export class QManager extends QPerson { + budget = new QNumberPath(this.withPrefix("Budget")); + bossOffice = new QEntityPath(this.withPrefix("BossOffice"), () => QLocation); + directReports = new QEntityCollectionPath(this.withPrefix("DirectReports"), () => QPerson); +} +export const qManager = new QManager(); +export class QLocation extends QueryObject { + address = new QStringPath(this.withPrefix("Address")); + city = new QEntityPath(this.withPrefix("City"), () => QCity); +} +export const qLocation = new QLocation(); +export class QCity extends QueryObject { + name = new QStringPath(this.withPrefix("Name")); + countryRegion = new QStringPath(this.withPrefix("CountryRegion")); + region = new QStringPath(this.withPrefix("Region")); +} +export const qCity = new QCity(); +export class QAirportLocation extends QLocation { + loc = new QStringPath(this.withPrefix("Loc")); +} +export const qAirportLocation = new QAirportLocation(); +export class QEventLocation extends QLocation { + buildingInfo = new QStringPath(this.withPrefix("BuildingInfo")); +} +export const qEventLocation = new QEventLocation(); +export class QGetPersonWithMostFriends extends QFunction { + params = []; + constructor() { + super("GetPersonWithMostFriends", new OperationReturnType(ReturnTypes.COMPLEX, new QComplexParam("NONE", new QPerson))); + } + getParams() { + return this.params; + } + buildUrl() { + return super.buildUrl(undefined); + } +} +export class QGetNearestAirport extends QFunction { + params = [new QNumberParam("lat"), new QNumberParam("lon")]; + constructor() { + super("GetNearestAirport", new OperationReturnType(ReturnTypes.COMPLEX, new QComplexParam("NONE", new QAirport))); + } + getParams() { + return this.params; + } +} +export class QResetDataSource extends QAction { + params = []; + constructor() { + super("ResetDataSource"); + } + getParams() { + return this.params; + } +} diff --git a/.vitepress/theme/model/trippin/TrippinModel.d.ts b/.vitepress/theme/model/trippin/TrippinModel.d.ts new file mode 100644 index 0000000000..a9de8fb2e0 --- /dev/null +++ b/.vitepress/theme/model/trippin/TrippinModel.d.ts @@ -0,0 +1,608 @@ +export declare enum PersonGender { + Male = "Male", + Female = "Female", + Unknown = "Unknown" +} +export declare enum Feature { + Feature1 = "Feature1", + Feature2 = "Feature2", + Feature3 = "Feature3", + Feature4 = "Feature4" +} +export interface Person { + /** + * **Key Property**: This is a key property used to identify the entity.
**Managed**: This property is managed on the server side and cannot be edited. + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `UserName` | + * | Type | `Edm.String` | + * | Nullable | `false` | + */ + userName: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `FirstName` | + * | Type | `Edm.String` | + * | Nullable | `false` | + */ + firstName: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `LastName` | + * | Type | `Edm.String` | + */ + lastName: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `MiddleName` | + * | Type | `Edm.String` | + */ + middleName: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Gender` | + * | Type | `Trippin.PersonGender` | + * | Nullable | `false` | + */ + gender: PersonGender; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Age` | + * | Type | `Edm.Int64` | + */ + age: number | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Emails` | + * | Type | `Collection(Edm.String)` | + */ + emails: Array; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `AddressInfo` | + * | Type | `Collection(Trippin.Location)` | + */ + addressInfo: Array; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `HomeAddress` | + * | Type | `Trippin.Location` | + */ + homeAddress: Location | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `FavoriteFeature` | + * | Type | `Trippin.Feature` | + * | Nullable | `false` | + */ + favoriteFeature: Feature; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Features` | + * | Type | `Collection(Trippin.Feature)` | + * | Nullable | `false` | + */ + features: Array; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Friends` | + * | Type | `Collection(Trippin.Person)` | + */ + friends?: Array; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `BestFriend` | + * | Type | `Trippin.Person` | + */ + bestFriend?: Person | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Trips` | + * | Type | `Collection(Trippin.Trip)` | + */ + trips?: Array; +} +export type PersonId = string | { + userName: string; +}; +export interface EditablePerson extends Pick, Partial> { + addressInfo?: Array; + homeAddress?: EditableLocation | null; +} +export interface Person_GetFriendsTripsParams { + userName: string; +} +export interface Person_UpdateLastNameParams { + lastName: string; +} +export interface Person_ShareTripParams { + userName: string; + tripId: number; +} +export interface Airline { + /** + * **Key Property**: This is a key property used to identify the entity.
**Managed**: This property is managed on the server side and cannot be edited. + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `AirlineCode` | + * | Type | `Edm.String` | + * | Nullable | `false` | + */ + airlineCode: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Name` | + * | Type | `Edm.String` | + */ + name: string | null; +} +export type AirlineId = string | { + airlineCode: string; +}; +export interface EditableAirline extends Partial> { +} +export interface Airport { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Name` | + * | Type | `Edm.String` | + */ + name: string | null; + /** + * **Key Property**: This is a key property used to identify the entity.
**Managed**: This property is managed on the server side and cannot be edited. + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `IcaoCode` | + * | Type | `Edm.String` | + * | Nullable | `false` | + */ + icaoCode: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `IataCode` | + * | Type | `Edm.String` | + */ + iataCode: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Location` | + * | Type | `Trippin.AirportLocation` | + */ + location: AirportLocation | null; +} +export type AirportId = string | { + icaoCode: string; +}; +export interface EditableAirport extends Partial> { + location?: EditableAirportLocation | null; +} +export interface Trip { + /** + * **Key Property**: This is a key property used to identify the entity.
**Managed**: This property is managed on the server side and cannot be edited. + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `TripId` | + * | Type | `Edm.Int32` | + * | Nullable | `false` | + */ + tripId: number; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `ShareId` | + * | Type | `Edm.Guid` | + * | Nullable | `false` | + */ + shareId: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Name` | + * | Type | `Edm.String` | + */ + name: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Budget` | + * | Type | `Edm.Single` | + * | Nullable | `false` | + */ + budget: number; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Description` | + * | Type | `Edm.String` | + */ + description: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Tags` | + * | Type | `Collection(Edm.String)` | + */ + tags: Array; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `StartsAt` | + * | Type | `Edm.DateTimeOffset` | + * | Nullable | `false` | + */ + startsAt: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `EndsAt` | + * | Type | `Edm.DateTimeOffset` | + * | Nullable | `false` | + */ + endsAt: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `PlanItems` | + * | Type | `Collection(Trippin.PlanItem)` | + */ + planItems?: Array; +} +export type TripId = number | { + tripId: number; +}; +export interface EditableTrip extends Pick, Partial> { +} +export interface PlanItem { + /** + * **Key Property**: This is a key property used to identify the entity.
**Managed**: This property is managed on the server side and cannot be edited. + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `PlanItemId` | + * | Type | `Edm.Int32` | + * | Nullable | `false` | + */ + planItemId: number; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `ConfirmationCode` | + * | Type | `Edm.String` | + */ + confirmationCode: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `StartsAt` | + * | Type | `Edm.DateTimeOffset` | + * | Nullable | `false` | + */ + startsAt: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `EndsAt` | + * | Type | `Edm.DateTimeOffset` | + * | Nullable | `false` | + */ + endsAt: string; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Duration` | + * | Type | `Edm.Duration` | + * | Nullable | `false` | + */ + duration: string; +} +export type PlanItemId = number | { + planItemId: number; +}; +export interface EditablePlanItem extends Pick, Partial> { +} +export interface Event extends PlanItem { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `OccursAt` | + * | Type | `Trippin.EventLocation` | + */ + occursAt: EventLocation | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Description` | + * | Type | `Edm.String` | + */ + description: string | null; +} +export interface EditableEvent extends Pick, Partial> { + occursAt?: EditableEventLocation | null; +} +export interface PublicTransportation extends PlanItem { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `SeatNumber` | + * | Type | `Edm.String` | + */ + seatNumber: string | null; +} +export interface EditablePublicTransportation extends Pick, Partial> { +} +export interface Flight extends PublicTransportation { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `FlightNumber` | + * | Type | `Edm.String` | + */ + flightNumber: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Airline` | + * | Type | `Trippin.Airline` | + */ + airline?: Airline | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `From` | + * | Type | `Trippin.Airport` | + */ + from?: Airport | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `To` | + * | Type | `Trippin.Airport` | + */ + to?: Airport | null; +} +export interface EditableFlight extends Pick, Partial> { +} +export interface Employee extends Person { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Cost` | + * | Type | `Edm.Int64` | + * | Nullable | `false` | + */ + cost: number; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Peers` | + * | Type | `Collection(Trippin.Person)` | + */ + peers?: Array; +} +export interface EditableEmployee extends Pick, Partial> { + addressInfo?: Array; + homeAddress?: EditableLocation | null; +} +export interface Manager extends Person { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Budget` | + * | Type | `Edm.Int64` | + * | Nullable | `false` | + */ + budget: number; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `BossOffice` | + * | Type | `Trippin.Location` | + */ + bossOffice: Location | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `DirectReports` | + * | Type | `Collection(Trippin.Person)` | + */ + directReports?: Array; +} +export interface EditableManager extends Pick, Partial> { + addressInfo?: Array; + homeAddress?: EditableLocation | null; + bossOffice?: EditableLocation | null; +} +export interface Location { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Address` | + * | Type | `Edm.String` | + */ + address: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `City` | + * | Type | `Trippin.City` | + */ + city: City | null; +} +export interface EditableLocation extends Partial> { + city?: EditableCity | null; +} +export interface City { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Name` | + * | Type | `Edm.String` | + */ + name: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `CountryRegion` | + * | Type | `Edm.String` | + */ + countryRegion: string | null; + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Region` | + * | Type | `Edm.String` | + */ + region: string | null; +} +export interface EditableCity extends Partial> { +} +export interface AirportLocation extends Location { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `Loc` | + * | Type | `Edm.GeographyPoint` | + */ + loc: string | null; +} +export interface EditableAirportLocation extends Partial> { + city?: EditableCity | null; +} +export interface EventLocation extends Location { + /** + * + * OData Attributes: + * |Attribute Name | Attribute Value | + * | --- | ---| + * | Name | `BuildingInfo` | + * | Type | `Edm.String` | + */ + buildingInfo: string | null; +} +export interface EditableEventLocation extends Partial> { + city?: EditableCity | null; +} +export interface GetNearestAirportParams { + lat: number; + lon: number; +} diff --git a/.vitepress/theme/model/trippin/TrippinModel.js b/.vitepress/theme/model/trippin/TrippinModel.js new file mode 100644 index 0000000000..0613b7d973 --- /dev/null +++ b/.vitepress/theme/model/trippin/TrippinModel.js @@ -0,0 +1,13 @@ +export var PersonGender; +(function (PersonGender) { + PersonGender["Male"] = "Male"; + PersonGender["Female"] = "Female"; + PersonGender["Unknown"] = "Unknown"; +})(PersonGender || (PersonGender = {})); +export var Feature; +(function (Feature) { + Feature["Feature1"] = "Feature1"; + Feature["Feature2"] = "Feature2"; + Feature["Feature3"] = "Feature3"; + Feature["Feature4"] = "Feature4"; +})(Feature || (Feature = {})); diff --git a/.vitepress/theme/model/trippin/TrippinService.d.ts b/.vitepress/theme/model/trippin/TrippinService.d.ts new file mode 100644 index 0000000000..8b58aa3a39 --- /dev/null +++ b/.vitepress/theme/model/trippin/TrippinService.d.ts @@ -0,0 +1,172 @@ +import { ODataModelResponseV4, ODataCollectionResponseV4, ODataValueResponseV4 } from "@odata2ts/odata-core"; +import { QStringCollection, StringCollection, QEnumCollection, EnumCollection } from "@odata2ts/odata-query-objects"; +import { ODataHttpClient, ODataHttpClientConfig, ODataResponse } from "@odata2ts/http-client-api"; +import { ODataService, EntityTypeServiceV4, CollectionServiceV4, EntitySetServiceV4 } from "@odata2ts/odata-service"; +import { PersonId, AirlineId, AirportId, Person, Airport, GetNearestAirportParams, EditablePerson, Location, EditableLocation, Feature, TripId, Airline, Trip, Person_GetFriendsTripsParams, Person_UpdateLastNameParams, Person_ShareTripParams, EditableAirline, EditableAirport, EditableTrip, PlanItemId, PlanItem, EditablePlanItem, Event, EditableEvent, PublicTransportation, EditablePublicTransportation, Flight, EditableFlight, Employee, EditableEmployee, Manager, EditableManager, City, EditableCity, AirportLocation, EditableAirportLocation, EventLocation, EditableEventLocation } from "./TrippinModel"; +import { QPerson, QLocation, QAirline, QAirport, QTrip, QPlanItem, QEvent, QPublicTransportation, QFlight, QEmployee, QManager, QCity, QAirportLocation, QEventLocation } from "./QTrippin"; +export declare class TrippinService extends ODataService { + private _me?; + private _qGetPersonWithMostFriends?; + private _qGetNearestAirport?; + private _qResetDataSource?; + people(): PersonCollectionService; + people(id: PersonId): PersonService; + airlines(): AirlineCollectionService; + airlines(id: AirlineId): AirlineService; + airports(): AirportCollectionService; + airports(id: AirportId): AirportService; + me(): PersonService; + getPersonWithMostFriends(requestConfig?: ODataHttpClientConfig): ODataResponse>; + getNearestAirport(params: GetNearestAirportParams, requestConfig?: ODataHttpClientConfig): ODataResponse>; + resetDataSource(requestConfig?: ODataHttpClientConfig): ODataResponse>; +} +export declare class PersonService extends EntityTypeServiceV4 { + private _emails?; + private _addressInfo?; + private _homeAddress?; + private _features?; + private _bestFriend?; + private _personQGetFavoriteAirline?; + private _personQGetFriendsTrips?; + private _personQUpdateLastName?; + private _personQShareTrip?; + constructor(client: ClientType, basePath: string, name: string); + emails(): CollectionServiceV4; + addressInfo(): CollectionServiceV4; + homeAddress(): LocationService; + features(): CollectionServiceV4, QEnumCollection, Feature>; + friends(): PersonCollectionService; + friends(id: PersonId): PersonService; + bestFriend(): PersonService; + trips(): TripCollectionService; + trips(id: TripId): TripService; + getFavoriteAirline(requestConfig?: ODataHttpClientConfig): ODataResponse>; + getFriendsTrips(params: Person_GetFriendsTripsParams, requestConfig?: ODataHttpClientConfig): ODataResponse>; + updateLastName(params: Person_UpdateLastNameParams, requestConfig?: ODataHttpClientConfig): ODataResponse>; + shareTrip(params: Person_ShareTripParams, requestConfig?: ODataHttpClientConfig): ODataResponse>; +} +export declare class PersonCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class AirlineService extends EntityTypeServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class AirlineCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class AirportService extends EntityTypeServiceV4 { + private _location?; + constructor(client: ClientType, basePath: string, name: string); + location(): AirportLocationService; +} +export declare class AirportCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class TripService extends EntityTypeServiceV4 { + private _tags?; + private _tripQGetInvolvedPeople?; + constructor(client: ClientType, basePath: string, name: string); + tags(): CollectionServiceV4; + planItems(): PlanItemCollectionService; + planItems(id: PlanItemId): PlanItemService; + getInvolvedPeople(requestConfig?: ODataHttpClientConfig): ODataResponse>; +} +export declare class TripCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class PlanItemService extends EntityTypeServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class PlanItemCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class EventService extends EntityTypeServiceV4 { + private _occursAt?; + constructor(client: ClientType, basePath: string, name: string); + occursAt(): EventLocationService; +} +export declare class EventCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class PublicTransportationService extends EntityTypeServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class PublicTransportationCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class FlightService extends EntityTypeServiceV4 { + private _airline?; + private _from?; + private _to?; + constructor(client: ClientType, basePath: string, name: string); + airline(): AirlineService; + from(): AirportService; + to(): AirportService; +} +export declare class FlightCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class EmployeeService extends EntityTypeServiceV4 { + private _emails?; + private _addressInfo?; + private _homeAddress?; + private _features?; + private _bestFriend?; + constructor(client: ClientType, basePath: string, name: string); + emails(): CollectionServiceV4; + addressInfo(): CollectionServiceV4; + homeAddress(): LocationService; + features(): CollectionServiceV4, QEnumCollection, Feature>; + friends(): PersonCollectionService; + friends(id: PersonId): PersonService; + bestFriend(): PersonService; + trips(): TripCollectionService; + trips(id: TripId): TripService; + peers(): PersonCollectionService; + peers(id: PersonId): PersonService; +} +export declare class EmployeeCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class ManagerService extends EntityTypeServiceV4 { + private _emails?; + private _addressInfo?; + private _homeAddress?; + private _features?; + private _bestFriend?; + private _bossOffice?; + constructor(client: ClientType, basePath: string, name: string); + emails(): CollectionServiceV4; + addressInfo(): CollectionServiceV4; + homeAddress(): LocationService; + features(): CollectionServiceV4, QEnumCollection, Feature>; + friends(): PersonCollectionService; + friends(id: PersonId): PersonService; + bestFriend(): PersonService; + trips(): TripCollectionService; + trips(id: TripId): TripService; + bossOffice(): LocationService; + directReports(): PersonCollectionService; + directReports(id: PersonId): PersonService; +} +export declare class ManagerCollectionService extends EntitySetServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class LocationService extends EntityTypeServiceV4 { + private _city?; + constructor(client: ClientType, basePath: string, name: string); + city(): CityService; +} +export declare class CityService extends EntityTypeServiceV4 { + constructor(client: ClientType, basePath: string, name: string); +} +export declare class AirportLocationService extends EntityTypeServiceV4 { + private _city?; + constructor(client: ClientType, basePath: string, name: string); + city(): CityService; +} +export declare class EventLocationService extends EntityTypeServiceV4 { + private _city?; + constructor(client: ClientType, basePath: string, name: string); + city(): CityService; +} diff --git a/.vitepress/theme/model/trippin/TrippinService.js b/.vitepress/theme/model/trippin/TrippinService.js new file mode 100644 index 0000000000..0683512ed1 --- /dev/null +++ b/.vitepress/theme/model/trippin/TrippinService.js @@ -0,0 +1,495 @@ +import { qStringCollection, qEnumCollection } from "@odata2ts/odata-query-objects"; +import { ODataService, EntityTypeServiceV4, CollectionServiceV4, EntitySetServiceV4 } from "@odata2ts/odata-service"; +import { QPersonId, QAirlineId, QAirportId, QGetPersonWithMostFriends, QGetNearestAirport, QResetDataSource, qPerson, qLocation, QTripId, Person_QGetFavoriteAirline, Person_QGetFriendsTrips, Person_QUpdateLastName, Person_QShareTrip, qAirline, qAirport, qTrip, QPlanItemId, Trip_QGetInvolvedPeople, qPlanItem, qEvent, qPublicTransportation, qFlight, qEmployee, qManager, qCity, qAirportLocation, qEventLocation } from "./QTrippin"; +export class TrippinService extends ODataService { + _me; + _qGetPersonWithMostFriends; + _qGetNearestAirport; + _qResetDataSource; + people(id) { + const fieldName = "People"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } + airlines(id) { + const fieldName = "Airlines"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new AirlineCollectionService(client, path, fieldName) + : new AirlineService(client, path, new QAirlineId(fieldName).buildUrl(id)); + } + airports(id) { + const fieldName = "Airports"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new AirportCollectionService(client, path, fieldName) + : new AirportService(client, path, new QAirportId(fieldName).buildUrl(id)); + } + me() { + if (!this._me) { + const { client, path } = this.__base; + this._me = new PersonService(client, path, "Me"); + } + return this._me; + } + async getPersonWithMostFriends(requestConfig) { + if (!this._qGetPersonWithMostFriends) { + this._qGetPersonWithMostFriends = new QGetPersonWithMostFriends(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._qGetPersonWithMostFriends.buildUrl()); + const response = await client.get(url, requestConfig, getDefaultHeaders()); + return this._qGetPersonWithMostFriends.convertResponse(response); + } + async getNearestAirport(params, requestConfig) { + if (!this._qGetNearestAirport) { + this._qGetNearestAirport = new QGetNearestAirport(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._qGetNearestAirport.buildUrl(params)); + const response = await client.get(url, requestConfig, getDefaultHeaders()); + return this._qGetNearestAirport.convertResponse(response); + } + async resetDataSource(requestConfig) { + if (!this._qResetDataSource) { + this._qResetDataSource = new QResetDataSource(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._qResetDataSource.buildUrl()); + return client.post(url, {}, requestConfig, getDefaultHeaders()); + } +} +export class PersonService extends EntityTypeServiceV4 { + _emails; + _addressInfo; + _homeAddress; + _features; + _bestFriend; + _personQGetFavoriteAirline; + _personQGetFriendsTrips; + _personQUpdateLastName; + _personQShareTrip; + constructor(client, basePath, name) { + super(client, basePath, name, qPerson); + } + emails() { + if (!this._emails) { + const { client, path } = this.__base; + this._emails = new CollectionServiceV4(client, path, "Emails", qStringCollection); + } + return this._emails; + } + addressInfo() { + if (!this._addressInfo) { + const { client, path } = this.__base; + this._addressInfo = new CollectionServiceV4(client, path, "AddressInfo", qLocation); + } + return this._addressInfo; + } + homeAddress() { + if (!this._homeAddress) { + const { client, path } = this.__base; + this._homeAddress = new LocationService(client, path, "HomeAddress"); + } + return this._homeAddress; + } + features() { + if (!this._features) { + const { client, path } = this.__base; + this._features = new CollectionServiceV4(client, path, "Features", qEnumCollection); + } + return this._features; + } + friends(id) { + const fieldName = "Friends"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } + bestFriend() { + if (!this._bestFriend) { + const { client, path } = this.__base; + this._bestFriend = new PersonService(client, path, "BestFriend"); + } + return this._bestFriend; + } + trips(id) { + const fieldName = "Trips"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new TripCollectionService(client, path, fieldName) + : new TripService(client, path, new QTripId(fieldName).buildUrl(id)); + } + async getFavoriteAirline(requestConfig) { + if (!this._personQGetFavoriteAirline) { + this._personQGetFavoriteAirline = new Person_QGetFavoriteAirline(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._personQGetFavoriteAirline.buildUrl()); + const response = await client.get(url, requestConfig, getDefaultHeaders()); + return this._personQGetFavoriteAirline.convertResponse(response); + } + async getFriendsTrips(params, requestConfig) { + if (!this._personQGetFriendsTrips) { + this._personQGetFriendsTrips = new Person_QGetFriendsTrips(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._personQGetFriendsTrips.buildUrl(params)); + const response = await client.get(url, requestConfig, getDefaultHeaders()); + return this._personQGetFriendsTrips.convertResponse(response); + } + async updateLastName(params, requestConfig) { + if (!this._personQUpdateLastName) { + this._personQUpdateLastName = new Person_QUpdateLastName(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._personQUpdateLastName.buildUrl()); + const response = await client.post(url, this._personQUpdateLastName.convertUserParams(params), requestConfig, getDefaultHeaders()); + return this._personQUpdateLastName.convertResponse(response); + } + async shareTrip(params, requestConfig) { + if (!this._personQShareTrip) { + this._personQShareTrip = new Person_QShareTrip(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._personQShareTrip.buildUrl()); + return client.post(url, this._personQShareTrip.convertUserParams(params), requestConfig, getDefaultHeaders()); + } +} +export class PersonCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qPerson, new QPersonId(name)); + } +} +export class AirlineService extends EntityTypeServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qAirline); + } +} +export class AirlineCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qAirline, new QAirlineId(name)); + } +} +export class AirportService extends EntityTypeServiceV4 { + _location; + constructor(client, basePath, name) { + super(client, basePath, name, qAirport); + } + location() { + if (!this._location) { + const { client, path } = this.__base; + this._location = new AirportLocationService(client, path, "Location"); + } + return this._location; + } +} +export class AirportCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qAirport, new QAirportId(name)); + } +} +export class TripService extends EntityTypeServiceV4 { + _tags; + _tripQGetInvolvedPeople; + constructor(client, basePath, name) { + super(client, basePath, name, qTrip); + } + tags() { + if (!this._tags) { + const { client, path } = this.__base; + this._tags = new CollectionServiceV4(client, path, "Tags", qStringCollection); + } + return this._tags; + } + planItems(id) { + const fieldName = "PlanItems"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PlanItemCollectionService(client, path, fieldName) + : new PlanItemService(client, path, new QPlanItemId(fieldName).buildUrl(id)); + } + async getInvolvedPeople(requestConfig) { + if (!this._tripQGetInvolvedPeople) { + this._tripQGetInvolvedPeople = new Trip_QGetInvolvedPeople(); + } + const { addFullPath, client, getDefaultHeaders } = this.__base; + const url = addFullPath(this._tripQGetInvolvedPeople.buildUrl()); + const response = await client.get(url, requestConfig, getDefaultHeaders()); + return this._tripQGetInvolvedPeople.convertResponse(response); + } +} +export class TripCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qTrip, new QTripId(name)); + } +} +export class PlanItemService extends EntityTypeServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qPlanItem); + } +} +export class PlanItemCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qPlanItem, new QPlanItemId(name)); + } +} +export class EventService extends EntityTypeServiceV4 { + _occursAt; + constructor(client, basePath, name) { + super(client, basePath, name, qEvent); + } + occursAt() { + if (!this._occursAt) { + const { client, path } = this.__base; + this._occursAt = new EventLocationService(client, path, "OccursAt"); + } + return this._occursAt; + } +} +export class EventCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qEvent, new QPlanItemId(name)); + } +} +export class PublicTransportationService extends EntityTypeServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qPublicTransportation); + } +} +export class PublicTransportationCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qPublicTransportation, new QPlanItemId(name)); + } +} +export class FlightService extends EntityTypeServiceV4 { + _airline; + _from; + _to; + constructor(client, basePath, name) { + super(client, basePath, name, qFlight); + } + airline() { + if (!this._airline) { + const { client, path } = this.__base; + this._airline = new AirlineService(client, path, "Airline"); + } + return this._airline; + } + from() { + if (!this._from) { + const { client, path } = this.__base; + this._from = new AirportService(client, path, "From"); + } + return this._from; + } + to() { + if (!this._to) { + const { client, path } = this.__base; + this._to = new AirportService(client, path, "To"); + } + return this._to; + } +} +export class FlightCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qFlight, new QPlanItemId(name)); + } +} +export class EmployeeService extends EntityTypeServiceV4 { + _emails; + _addressInfo; + _homeAddress; + _features; + _bestFriend; + constructor(client, basePath, name) { + super(client, basePath, name, qEmployee); + } + emails() { + if (!this._emails) { + const { client, path } = this.__base; + this._emails = new CollectionServiceV4(client, path, "Emails", qStringCollection); + } + return this._emails; + } + addressInfo() { + if (!this._addressInfo) { + const { client, path } = this.__base; + this._addressInfo = new CollectionServiceV4(client, path, "AddressInfo", qLocation); + } + return this._addressInfo; + } + homeAddress() { + if (!this._homeAddress) { + const { client, path } = this.__base; + this._homeAddress = new LocationService(client, path, "HomeAddress"); + } + return this._homeAddress; + } + features() { + if (!this._features) { + const { client, path } = this.__base; + this._features = new CollectionServiceV4(client, path, "Features", qEnumCollection); + } + return this._features; + } + friends(id) { + const fieldName = "Friends"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } + bestFriend() { + if (!this._bestFriend) { + const { client, path } = this.__base; + this._bestFriend = new PersonService(client, path, "BestFriend"); + } + return this._bestFriend; + } + trips(id) { + const fieldName = "Trips"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new TripCollectionService(client, path, fieldName) + : new TripService(client, path, new QTripId(fieldName).buildUrl(id)); + } + peers(id) { + const fieldName = "Peers"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } +} +export class EmployeeCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qEmployee, new QPersonId(name)); + } +} +export class ManagerService extends EntityTypeServiceV4 { + _emails; + _addressInfo; + _homeAddress; + _features; + _bestFriend; + _bossOffice; + constructor(client, basePath, name) { + super(client, basePath, name, qManager); + } + emails() { + if (!this._emails) { + const { client, path } = this.__base; + this._emails = new CollectionServiceV4(client, path, "Emails", qStringCollection); + } + return this._emails; + } + addressInfo() { + if (!this._addressInfo) { + const { client, path } = this.__base; + this._addressInfo = new CollectionServiceV4(client, path, "AddressInfo", qLocation); + } + return this._addressInfo; + } + homeAddress() { + if (!this._homeAddress) { + const { client, path } = this.__base; + this._homeAddress = new LocationService(client, path, "HomeAddress"); + } + return this._homeAddress; + } + features() { + if (!this._features) { + const { client, path } = this.__base; + this._features = new CollectionServiceV4(client, path, "Features", qEnumCollection); + } + return this._features; + } + friends(id) { + const fieldName = "Friends"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } + bestFriend() { + if (!this._bestFriend) { + const { client, path } = this.__base; + this._bestFriend = new PersonService(client, path, "BestFriend"); + } + return this._bestFriend; + } + trips(id) { + const fieldName = "Trips"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new TripCollectionService(client, path, fieldName) + : new TripService(client, path, new QTripId(fieldName).buildUrl(id)); + } + bossOffice() { + if (!this._bossOffice) { + const { client, path } = this.__base; + this._bossOffice = new LocationService(client, path, "BossOffice"); + } + return this._bossOffice; + } + directReports(id) { + const fieldName = "DirectReports"; + const { client, path } = this.__base; + return typeof id === "undefined" || id === null + ? new PersonCollectionService(client, path, fieldName) + : new PersonService(client, path, new QPersonId(fieldName).buildUrl(id)); + } +} +export class ManagerCollectionService extends EntitySetServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qManager, new QPersonId(name)); + } +} +export class LocationService extends EntityTypeServiceV4 { + _city; + constructor(client, basePath, name) { + super(client, basePath, name, qLocation); + } + city() { + if (!this._city) { + const { client, path } = this.__base; + this._city = new CityService(client, path, "City"); + } + return this._city; + } +} +export class CityService extends EntityTypeServiceV4 { + constructor(client, basePath, name) { + super(client, basePath, name, qCity); + } +} +export class AirportLocationService extends EntityTypeServiceV4 { + _city; + constructor(client, basePath, name) { + super(client, basePath, name, qAirportLocation); + } + city() { + if (!this._city) { + const { client, path } = this.__base; + this._city = new CityService(client, path, "City"); + } + return this._city; + } +} +export class EventLocationService extends EntityTypeServiceV4 { + _city; + constructor(client, basePath, name) { + super(client, basePath, name, qEventLocation); + } + city() { + if (!this._city) { + const { client, path } = this.__base; + this._city = new CityService(client, path, "City"); + } + return this._city; + } +} diff --git a/docs/pages/Benchmarking.md b/docs/Benchmarking.md similarity index 99% rename from docs/pages/Benchmarking.md rename to docs/Benchmarking.md index 6befa5d9c5..b32d5bf930 100644 --- a/docs/pages/Benchmarking.md +++ b/docs/Benchmarking.md @@ -67,6 +67,7 @@ The following is a walk-through on how to evaluate the performance impact of an UI5_CLI_NO_LOCAL=X node /my/home/ui5-tooling-benchmark/ui5-cli/bin/ui5.cjs --version ``` On Windows: + ```sh set UI5_CLI_NO_LOCAL=X node /my/home/ui5-tooling-benchmark/ui5-cli/bin/ui5.cjs --version ``` @@ -88,6 +89,7 @@ The following is a walk-through on how to evaluate the performance impact of an --export-markdown ./baseline.md ``` On Windows: + ```sh hyperfine --warmup 1 \ 'set UI5_CLI_NO_LOCAL=X node /my/home/ui5-tooling-benchmark/ui5-cli/bin/ui5.cjs build' \ @@ -118,6 +120,7 @@ The following is a walk-through on how to evaluate the performance impact of an --export-markdown ./my_change.md ``` On Windows: + ```sh hyperfine --warmup 1 \ 'set UI5_CLI_NO_LOCAL=X node /my/home/ui5-tooling-benchmark/ui5-cli/bin/ui5.cjs build' \ diff --git a/docs/pages/Builder.md b/docs/Builder.md similarity index 81% rename from docs/pages/Builder.md rename to docs/Builder.md index 2fd6b60e1d..e704121eaa 100644 --- a/docs/pages/Builder.md +++ b/docs/Builder.md @@ -6,7 +6,7 @@ Based on a project's type, the UI5 Builder defines a series of build steps to ex For every type there is a set of default tasks. You can disable single tasks using the `--exclude-task` [CLI parameter](./CLI.md#ui5-build), and you can include tasks using the `--include-task` parameter. -[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/index.html){: .md-button .sap-icon-initiative } +[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/index.html) ## Tasks Tasks are specific build steps to be executed during build phase. @@ -25,33 +25,33 @@ All available standard tasks are documented [in the API reference](https://sap.g | replaceCopyright | *enabled* | *enabled* | *enabled* | | replaceVersion | *enabled* | *enabled* | *enabled* | | replaceBuildtime | | *enabled* | | -| generateJsdoc | | *disabled* ^1^ | | -| executeJsdocSdkTransformation | | *disabled* ^1^ | | +| generateJsdoc | | *disabled¹* | | +| executeJsdocSdkTransformation | | *disabled¹* | | | minify | *enabled* | *enabled* | | | generateFlexChangesBundle | *enabled* | *enabled* | | | generateLibraryManifest | | *enabled* | | | enhanceManifest | *enabled* | *enabled* | | -| generateComponentPreload | *enabled* | *disabled* ^2^ | | +| generateComponentPreload | *enabled* | *disabled²* | | | generateLibraryPreload | | *enabled* | | -| generateStandaloneAppBundle | *disabled* ^3^ | | | -| transformBootstrapHtml | *disabled* ^3^ | | | -| generateBundle | *disabled* ^4^ | *disabled* ^4^ | | +| generateStandaloneAppBundle | *disabled³* | | | +| transformBootstrapHtml | *disabled³* | | | +| generateBundle | *disabled⁴* | *disabled⁴* | | | buildThemes | | *enabled* | *enabled* | -| generateThemeDesignerResources | | *disabled* ^5^ | *disabled* ^5^ | -| generateVersionInfo | *disabled* ^1^ | | | +| generateThemeDesignerResources | | *disabled⁵* | *disabled⁵* | +| generateVersionInfo | *disabled¹* | | | | generateCachebusterInfo | *disabled* | | | -| generateApiIndex | *disabled* ^1^ | | | +| generateApiIndex | *disabled¹ * | | | | generateResourcesJson | *disabled* | *disabled* | *disabled* | *Disabled tasks can be activated by certain build modes, the project configuration, or by using the `--include-task` [CLI parameter](./CLI.md#ui5-build). See footnotes where given* --- -^1^ Enabled in `jsdoc` build, which disables most of the other tasks -^2^ Enabled for projects defining a [component preload configuration](./Configuration.md#component-preload-generation) -^3^ Enabled in `self-contained` build, which disables `generateComponentPreload` and `generateLibraryPreload` -^4^ Enabled for projects defining a [bundle configuration](./Configuration.md#custom-bundling) -^5^ Can be enabled for framework projects via the `includeTask` option. For other projects, this task is skipped +¹ Enabled in `jsdoc` build, which disables most of the other tasks +² Enabled for projects defining a [component preload configuration](./Configuration.md#component-preload-generation) +³ Enabled in `self-contained` build, which disables `generateComponentPreload` and `generateLibraryPreload` +⁴ Enabled for projects defining a [bundle configuration](./Configuration.md#custom-bundling) +⁵ Can be enabled for framework projects via the `includeTask` option. For other projects, this task is skipped ### minify @@ -65,25 +65,26 @@ Related to this, the bundling tasks will also incorporate the generated source m #### Input Source Maps -!!! info - Support for input source maps has been added in UI5 CLI [`v3.7.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.7.0). +::: tip +Support for input source maps has been added in UI5 CLI [`v3.7.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.7.0). +::: For projects facilitating transpilation (such as TypeScript-based projects), it is commonly desired to debug in the browser using the original sources, e.g. TypeScript files. To make this work, the transpilation process first needs to create source maps and reference them in the generated JavaScript code. UI5 Tooling's `minify` task will then find this reference and incorporate the source map into the minification process. In the end, the minified JavaScript resources will reference an updated source map, which reflects the transpilation as well as the minification. The browser can use this to map every statement back to the original TypeScript file, making debugging a breeze. -!!! warning - If a resource has been modified by another build task before `minify` is executed, any referenced source map will be ignored. This is to ensure the integrity of the source maps in the build result. +::: warning +If a resource has been modified by another build task before `minify` is executed, any referenced source map will be ignored. This is to ensure the integrity of the source maps in the build result. - It is possible that the modification of the resource content is not reflected in the associated source map, rendering it corrupted. A corrupt source map can make it impossible to properly analyze and debug a resource in the browser development tools. - - Standard tasks which may modify resources without updating the associated source maps currently include `replaceVersion`, `replaceCopyright` and `replaceBuildtime`. +It is possible that the modification of the resource content is not reflected in the associated source map, rendering it corrupted. A corrupt source map can make it impossible to properly analyze and debug a resource in the browser development tools. +Standard tasks which may modify resources without updating the associated source maps currently include `replaceVersion`, `replaceCopyright` and `replaceBuildtime`. +::: Expand the block below to view a diagram illustrating the minification process and source map handling. -??? info "Minification Activity Diagram" - ![minify Task Activity](../images/UI5_Tooling/Task_Minify.svg){ loading=lazy } - +::: details Minification Activity Diagram +![minify Task Activity](images/UI5_Tooling/Task_Minify.svg){ loading=lazy } +::: ### Generation of Supported Locales @@ -166,17 +167,17 @@ If you see this error message, please adjust your code by applying one of the fo **Option 2**: Wrap the respective files manually in `sap.ui.define` modules as shown below: -!!! example - **Before**: - ```js - const myFancyModule = {}; - ``` - - **After**: - ```js - sap.ui.define([], () => { - "use strict"; - const myFancyModule = {}; - return myFancyModule; - }); - ``` +> [!IMPORTANT] Example +>**Before**: +>```js +>const myFancyModule = {}; +>``` +> +>**After**: +>```js +>sap.ui.define([], () => { +> "use strict"; +> const myFancyModule = {}; +> return myFancyModule; +>}); +>``` diff --git a/docs/pages/CodeAnalysis.md b/docs/CodeAnalysis.md similarity index 95% rename from docs/pages/CodeAnalysis.md rename to docs/CodeAnalysis.md index dca0f73b39..c1fa31380a 100644 --- a/docs/pages/CodeAnalysis.md +++ b/docs/CodeAnalysis.md @@ -88,27 +88,26 @@ The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless, The [XML Composite Analyzer](https://github.com/SAP/ui5-builder/blob/main/lib/lbt/analyzer/XMLCompositeAnalyzer.js) searches for the name of the configured fragment containing the **XMLComposite** control. -=== "Name of the XMLComposite is equal to fragment name" - - ```javascript hl_lines="4" - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - return XMLComposite.extend("composites.MyComposite", {} - }); - ``` - -=== "Dedicated fragment name" - - ```javascript hl_lines="5" - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - return XMLComposite.extend("composites.MyComposite", { - fragment: "composites.custom.MyComposite" - } - }); - ``` +::: code-group +```javascript [Name of the XMLComposite is equal to fragment name] {4} +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + return XMLComposite.extend("composites.MyComposite", {} +}); +``` + + +```javascript [Dedicated fragment name] {5} +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + return XMLComposite.extend("composites.MyComposite", { + fragment: "composites.custom.MyComposite" + } +}); +``` +::: ## Library Initialization diff --git a/docs/pages/Configuration.md b/docs/Configuration.md similarity index 64% rename from docs/pages/Configuration.md rename to docs/Configuration.md index 76714c0b93..14890d7b06 100644 --- a/docs/pages/Configuration.md +++ b/docs/Configuration.md @@ -1,84 +1,69 @@ # Configuration A projects UI5 Tooling configuration is typically located in a [YAML](https://yaml.org/) file named `ui5.yaml`, located in the root directory. - -!!! info - This document describes the configuration of UI5 Tooling-based projects and extensions. It represents **[Specification Version 3.0](#specification-versions)**. - +:::tip Info +This document describes the configuration of UI5 Tooling-basedprojectandextensions. It represents **[Specification Version 3](/docs/Configuration#specification-versions)**. +::: ## Validation / IDE support -Starting with [Specification Version 2.0](#specification-version-20) the configuration is validated according to a JSON schema. -The current version of the schema can be found here: https://sap.github.io/ui5-tooling/schema/ui5.yaml.json +Starting with [Specification Version 2.0](/docs/Configuration#specification-version-20) the configuration is validated according to a JSON schema. The current version of the schema can be found here: https://sap.github.io/ui5-tooling/schema/ui5.yaml.json -The schema is also part of the [JSON Schema Store Catalog](http://schemastore.org/json/) which is used by the [YAML Language Server](https://github.com/redhat-developer/yaml-language-server). -See the list of [clients](https://github.com/redhat-developer/yaml-language-server/blob/main/README.md#clients) to find extensions for various IDEs and editors. +The schema is also part of the [JSON Schema Store Catalog](http://schemastore.org/json/) which is used by the [YAML Language Server](https://github.com/redhat-developer/yaml-language-server). See the list of [clients](https://github.com/redhat-developer/yaml-language-server/blob/main/README.md#clients) to find extensions for various IDEs and editors. ## Example - ```yaml specVersion: "4.0" type: application|library|theme-library|module metadata: name: some.project.name ``` - ## General Configuration ### Specification Version and -Type -A project must define a specification version (`specVersion`), to which its configuration is compatible to. Also see [Specification Versions](#specification-versions). +A project must define a specification version (`specVersion`), to which its configuration is compatible to. Also see [Specification Versions](/docs/Configuration#specification-versions). In addition, a project must define a `type`. This can be either `application`, `library`, `theme-library` (since Specification Version 1.1), or `module`. The type defines the default path mappings and build tasks. See [UI5 Builder: Types](./Builder.md#types) for details. - -!!! example - - === "application" - - ```yaml - specVersion: "4.0" - type: application - ``` - - === "library" - - ```yaml - specVersion: "4.0" - type: library - ``` - - === "theme-library" - - ```yaml - specVersion: "4.0" - type: theme-library - ``` - - === "module" - - ```yaml - specVersion: "4.0" - type: module - ``` +> [!IMPORTANT] Example +>::: code-group +> +> +>```yaml [application] +>specVersion: "4.0" +>type: application +>``` +>```yaml [library] +>specVersion: "4.0" +>type: library +>``` +>```yaml [theme-library] +>specVersion: "4.0" +>type: theme-library +>``` +>```yaml [module] +>specVersion: "4.0" +>type: module +>``` +>::: ### Kind The configuration may also contain a `kind` property. This is used to differentiate between projects and extensions. -This configuration defaults to `kind: project`, which means you typically only need to specify it for extensions like [Custom Tasks](./extensibility//CustomTasks.md#custom-task-extension). +This configuration defaults to `kind: project`, which means you typically only need to specify it for extensions like [Custom Tasks](./extensibility/CustomTasks.md#custom-task-extension). ### Metadata -!!! example - ```yaml - metadata: - name: my.company.project - copyright: |- - My Project - * (c) Copyright 2009-${currentYear} My Company - * Licensed under the XYZ License, Version n - see LICENSE.txt. - ``` - +> [!IMPORTANT] Example +>```yaml +>metadata: +> name: my.company.project +> copyright: |- +> My Project +> * (c) Copyright 2009-${currentYear} My Company +> * Licensed under the XYZ License, Version n - see LICENSE.txt. +>``` #### name A project must have a `name`. @@ -117,82 +102,96 @@ Note that all configured paths must be written in POSIX (i.e. using only forward #### Available Path Mappings -=== "Applications" - - `webapp`: Mapped to runtime path `/` (root) - - ```yaml title="Default Configuration" - resources: - configuration: - paths: - webapp: webapp - ``` - -=== "Libraries" - - `src`: Mapped to runtime path `/resources` - - `test`: Mapped to runtime path `/test-resources` - - ```yaml title="Default Configuration" - resources: - configuration: - paths: - src: src - test: test - ``` - -=== "Modules" - Modules can map any virtual paths to any physical path within the project. - - However, it is recommended that modules include their namespace in the virtual path and use the `/resources` prefix (e.g. `/resources/my/library/module-xy/`) to avoid name clashes with other projects. - - ```yaml title="Example Configuration" - resources: - configuration: - paths: - /resources/my/library/module-xy/: lib - /resources/my/library/module-xy-min/: dist - ``` - -!!! example - For an application project with the following directory structure, you need the path mapping configuration given below: - - ``` hl_lines="3 4 5" title="Directory Structure" - my-app/ - \_ ui5.yaml - \_ lib/ - \_ js/ - \_ app/ - ``` - - ```yaml hl_lines="4" title="Path Mapping Configuration" - resources: - configuration: - paths: - webapp: lib/js/app - ``` +::: info Applications +- webapp: Mapped to runtime path `/` (root) + +```yaml [Applications] + +resources: + configuration: + paths: + webapp: webapp +``` +::: + -### Encoding of `*.properties` files -!!! info - This configuration is available since UI5 CLI [`v1.7.0`](https://github.com/SAP/ui5-cli/releases/tag/v1.7.0) +:::info Libraries + - src: Mapped to runtime path `/resources` +- test: Mapped to runtime path `/test-resources` +```yaml [Libraries] +resources: + configuration: + paths: + src: src + test: test +``` +::: + +::: info Modules +Modules can map any virtual paths to any physical path within the project. +However, it is recommended that modules include their namespace in thevirtual +path and use the `/resources` prefix (e.g. `/resources/my/librarymodule-xy/`) +to avoid name clashes with other projects. + +```yaml [Modules] +resources: + configuration: + paths: + /resources/my/library/module-xy/: lib + /resources/my/library/module-xy-min/: dist +``` + -!!! example - === "UTF-8" +::: - ```yaml - resources: - configuration: - propertiesFileSourceEncoding: UTF-8 - ``` - === "ISO-8859-1" - ```yaml - resources: - configuration: - propertiesFileSourceEncoding: ISO-8859-1 - ``` +> [!IMPORTANT] Example +>For an application project with the following directory structure, youneed the path mapping configuration given below: +>Directory Structure: +>```yaml [Directory Structure] +>my-app/ +>\_ ui5.yaml +>\_ lib/ // [!code focus] +> \_ js/ // [!code focus] +> \_ app/ // [!code focus] +> +>``` +> Path Mapping Configuration: +>```yaml [Path Mapping Configuration] +>resources: +> configuration: +> paths: +> webapp: lib/js/app // [!code focus] +>``` +> +### Encoding of `*.properties` files + +> [!Tip] Info +>This configuration is available since UI5 CLI [`v1.7.0`](https://github.com/SAP/ui5-cli/releases/tag/v1.7.0) +> + + +> [!IMPORTANT] Example +>::: code-group +> +>```yaml [UTF-8] +>resources: +> configuration: +> propertiesFileSourceEncoding: UTF-8 +>``` +> +>```yaml [ISO-8859-1] +>resources: +> configuration: +> propertiesFileSourceEncoding: ISO-8859-1 +>``` +> +>::: +> By default UI5 Tooling expects different encodings for `*.properties` i18n files, depending on the project's specification version: Specification Version | Default `propertiesFileSourceEncoding` @@ -206,20 +205,22 @@ UI5 Tooling will read the corresponding files of the project in the given encodi ## Custom Configuration -!!! info - This configuration is available since UI5 CLI [`v2.2.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.2.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.1 or higher. - -!!! example - ```yaml - customConfiguration: - myTool: - key: value - myOtherTool: - otherKey: otherValue - ``` - +::: tip Info +This configuration is available since UI5 CLI [`v2.2.0`](https://githubcom/SAP/ui5-cli/releases/tag/v2.2.0) +and applies only to projects defining [Specification Version](/CODE_OF_CONDUCT.mddocs/Configuration/#specification-versions) +2.1 or higher. +::: + +> [!IMPORTANT] Example +> +>```yaml +>customConfiguration: +> myTool: +> key: value +> myOtherTool: +> otherKey: otherValue +>``` +> Custom configuration that is ignored by UI5 Tooling. This can be used to store UI5 specific configuration for third-party tools. @@ -228,30 +229,30 @@ For third-party tools it is recommended to follow a namespace-like structure. ## Framework Configuration -!!! info - This configuration is available since UI5 CLI [`v2.0.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.0.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.0 or higher. - +::: tip Info +This configuration is available since UI5 CLI [`v2.0.0`](https://githubcom/SAP/ui5-cli/releases/tag/v2.0.0) +and applies only to projects defining [Specification Version(#specification-versions) +2.0 or higher. +::: Define your project's framework dependencies. ### Framework and Version In your project's framework configuration you must define whether you want to use the OpenUI5 or the SAPUI5 framework and which version: -=== "OpenUI5" - ```yaml - framework: - name: OpenUI5 - version: 1.82.0 - ``` +::: code-group -=== "SAPUI5" - ```yaml - framework: - name: SAPUI5 - version: 1.82.0 - ``` +```yaml [OpenUI5] +framework: + name: OpenUI5 + version: 1.82.0 +``` +```yaml [SAPUI5] +framework: + name: SAPUI5 + version: 1.82.0 +``` +::: If you are not sure which framework is right for you, see our [documentation on the differences between OpenUI5 and SAPUI5](./FAQ.md##whats-the-difference-between-openui5-and-sapui5). @@ -262,81 +263,83 @@ You can find an overview of the available versions for each framework here: - [**SAPUI5** Version Overview](http://ui5.sap.com/versionoverview.html) - *The lowest version supported by UI5 Tooling is __1.76.0__* -!!! info - Projects that use the OpenUI5 framework cannot depend on projects that use the SAPUI5 framework. +::: tip Info +Projects that use the OpenUI5 framework cannot depend on projects thatuse the SAPUI5 framework. +::: ### Dependencies - -!!! example - === "application" - ```yaml - specVersion: "4.0" - type: application - metadata: - name: my.company.app - framework: - name: OpenUI5 - version: 1.82.0 - libraries: - - name: sap.ui.core - - name: sap.m - - name: sap.ui.table - - name: themelib_sap_fiori_3 - ``` - - === "library" - ```yaml - specVersion: "4.0" - type: library - metadata: - name: my.company.library - framework: - name: SAPUI5 - version: 1.82.0 - libraries: - - name: sap.ui.core - - name: sap.m - - name: themelib_sap_belize - optional: true - - name: themelib_sap_bluecrystal - optional: true - - name: themelib_sap_fiori_3 - optional: true - ``` - - When building an application depending on this library as well as one of the theme libraries, only that theme is built for this library. +> [!IMPORTANT] Example +> +>::: code-group +> +> ```yaml [application] +> specVersion: "4.0" +> type: application +> metadata: +> name: my.company.app +> framework: +> name: OpenUI5 +> version: 1.82.0 +> libraries: +> - name: sap.ui.core +> - name: sap.m +> - name: sap.ui.table +> - name: themelib_sap_fiori_3 +> ``` +> +> ```yaml [library] +> specVersion: "4.0" +> type: library +> metadata: +> name: my.company.library +> framework: +> name: SAPUI5 +> version: 1.82.0 +> libraries: +> - name: sap.ui.core +> - name: sap.m +> - name: themelib_sap_belize +> optional: true +> - name: themelib_sap_bluecrystal +> optional: true +> - name: themelib_sap_fiori_3 +> optional: true +> ``` +> ::: + +When building an application depending on this library as well as one of the theme libraries, only that theme is built for this library. #### Runtime Dependencies All libraries required by your project must be listed in the `libraries` section of the framework configuration: +::: code-group + +```yaml [OpenUI5] {4-7} +framework: + name: OpenUI5 + version: 1.82.0 + libraries: + - name: sap.ui.core + - name: sap.m + - name: sap.ui.table +``` -=== "OpenUI5" - ```yaml hl_lines="4-7" - framework: - name: OpenUI5 - version: 1.82.0 - libraries: - - name: sap.ui.core - - name: sap.m - - name: sap.ui.table - ``` - -=== "SAPUI5" - ```yaml hl_lines="4-7" - framework: - name: SAPUI5 - version: 1.82.0 - libraries: - - name: sap.ui.core - - name: sap.m - - name: sap.ui.comp - ``` +```yaml [SAPUI5] {4-7} +framework: + name: SAPUI5 + version: 1.82.0 + libraries: + - name: sap.ui.core + - name: sap.m + - name: sap.ui.comp +``` +::: #### Development Dependencies Development dependencies are only installed if the project defining them is the current root project. They are typically only required during the development of the project. -```yaml hl_lines="3" +```yaml {3} libraries: - name: sap.ushell development: true @@ -348,7 +351,7 @@ Note that a development dependency cannot be optional and vice versa. Optional dependencies are installed either if the project defining them is the current root project or if the dependency is already part of the current dependency tree. A typical use case is libraries defining optional dependencies to all theme libraries they support. You can choose which theme library to use by the application that is consuming the library by declaring it as a non-optional dependency. -```yaml hl_lines="3" +```yaml {3} libraries: - name: themelib_sap_fiori_3 optional: true @@ -356,64 +359,67 @@ You can choose which theme library to use by the application that is consuming t ## Build Configuration ### Exclude Resources - -!!! example - === "application" - ```yaml - builder: - resources: - excludes: - # You can specify paths relative to the configured "webapp" directory - - "index.html" - # When defining absolute paths, make sure to specify the namespace plus the "/resources/" prefix - - "/resources/my/project/namespace/test/**" - ``` - - === "library or theme-library" - ```yaml - builder: - resources: - excludes: - # For libraries, all paths must be absolute, except for wildcards - - "/resources/some/project/name/test_results/**" - - "/test-resources/**" - - "!/test-resources/some/project/name/demo-app/**" - - "**/*.svg" - ``` - - === "module" - !!! info - For projects of type `module`, this configuration is available since UI5 CLI [`v3.5.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.5.0) - and applies only to projects defining [Specification Version](#specification-versions) 3.1 or higher. - ```yaml - builder: - resources: - excludes: - # For modules, all paths must be absolute, except for wildcards - - "/resources/my/library/module-xy/min/**" - - "!/resources/my/library/module-xy/min/module-xy-bundle.js" - - "**/*.svg" - ``` +> [!IMPORTANT] Example +>For projects of type `module`, this configuration is available since UI5CLI [`v3.5.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.5.0) +>and applies only to projects defining [Specification Version](#specification-versions) +> 3.1 or higher. +>:::code-group +> +>```yaml [application] +>builder: +> resources: +> excludes: +> # You can specify paths relative to the configured "webapp" directory +> - "index.html" +> # When defining absolute paths, make sure to specify the namespace plus the "/resources/" prefix +> - "/resources/my/project/namespace/test/**" +>``` +> +>```yaml [library or theme-library] +>builder: +> resources: +> excludes: +> # For libraries, all paths must be absolute, except for wildcards +> - "/resources/some/project/name/test_results/**" +> - "/test-resources/**" +> - "!/test-resources/some/project/name/demo-app/**" +> - "**/*.svg" +>``` +> +> +> +>```yaml [module] +>builder: +> resources: +> excludes: +> # For modules, all paths must be absolute, except for wildcards +> - "/resources/my/library/module-xy/min/**" +> - "!/resources/my/library/module-xy/min/module-xy-bundle.js" +> - "**/*.svg" +>``` +> You can exclude a projects resources from the build process using a list of glob patterns. Matching resources will be ignored by the builder and all build tasks. Patterns are applied to the **virtual resource paths** (i.e. the UI5 runtime paths). Exclude patterns are always applied after any includes. ### Cachebuster - -!!! example - === "time (default)" - ```yaml - builder: - cachebuster: - signatureType: time - ``` - === "hash" - ```yaml - builder: - cachebuster: - signatureType: hash - ``` +> [!IMPORTANT] Example +> +>::: code-group +> +>```yaml [time (default)] +>builder: +> cachebuster: +> signatureType: time +>``` +> +>```yaml [hash] +>builder: +> cachebuster: +> signatureType: hash +>``` +> By default, the generated cachebuster info file signatures are based on timestamps (`time`). In setups like CI environments, a mechanism based on file hashes (`hash`) might be more reliable. Also see [PR #241](https://github.com/SAP/ui5-builder/pull/241) for more details. @@ -429,61 +435,61 @@ There are two ways to define the set of components for which preload bundles sho #### paths -!!! example - ```yaml - builder: - componentPreload: - paths: - - "my/awesome/app/**/Component.js" - ``` +> [!IMPORTANT] Example +>```yaml +>builder: +> componentPreload: +> paths: +> - "my/awesome/app/**/Component.js" +>``` +> The `paths` option takes one or multiple patterns. For every matched file a separate `Component-preload.js` will be generated. Patterns are always applied relative to the project's virtual source directory `/resources/`. #### namespaces -!!! example - ```yaml - builder: - componentPreload: - namespaces: - - "my/awesome/app" - - "my/awesome/app/componentOne" - - "my/awesome/app/componentTwo" - ``` - +> [!IMPORTANT] Example +> +>```yaml +>builder: +> componentPreload: +> namespaces: +> - "my/awesome/app" +> - "my/awesome/app/componentOne" +> - "my/awesome/app/componentTwo" +> +>``` The `namespaces` option takes one or multiple component namespaces, which correspond to the directory structures. #### excludes -!!! info - This configuration is available since UI5 CLI [`v2.10.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.10.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.3 or higher. - -!!! example - === "Single Component" - - ```yaml - builder: - componentPreload: - excludes: - - "my/awesome/app/localService/**" - ``` - - === "Multiple Components" - - ```yaml - builder: - componentPreload: - namespaces: - - "my/awesome/app" - - "my/awesome/app/componentOne" - - "my/awesome/app/componentTwo" - excludes: - - "my/awesome/app/**/thirdparty/" - - "!my/awesome/app/componentTwo/thirdparty/NotExcluded.js" - ``` - +::: tip Info +This configuration is available since UI5 CLI [`v2.10.0`](https://githubcom/SAP/ui5-cli/releases/tag/v2.10.0) +and applies only to projects defining [Specification Version(#specification-versions) +2.3 or higher. +::: +> [!IMPORTANT] Example +>::: code-group +> +>```yaml [Single Component] +>builder: +> componentPreload: +> excludes: +> - "my/awesome/app/localService/**" +>``` +>```yaml [Multiple Components] +>builder: +> componentPreload: +> namespaces: +> - "my/awesome/app" +> - "my/awesome/app/componentOne" +> - "my/awesome/app/componentTwo" +> excludes: +> - "my/awesome/app/**/thirdparty/" +> - "!my/awesome/app/componentTwo/thirdparty/NotExcluded.js" +>``` +>::: +> List of modules declared as glob patterns (resource name patterns) that are excluded from the component preload bundles. Similarly to the use of a single `*` or double `**` asterisk, a pattern ending with a slash `/` denotes an arbitrary number of characters or folder names. Re-includes have to be marked with a leading exclamation mark `!`. The order of filters is relevant; a later inclusion overrides an earlier exclusion, and vice versa. Note that patterns are always applied relative to the project's virtual source directory `/resources/`. Re-includes must start with the namespace of the component they apply to. @@ -494,38 +500,41 @@ For projects of type `library` a `library-preload.js` bundle is generated by def #### excludes -!!! info - This configuration is available since UI5 CLI [`v2.10.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.10.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.3 or higher. - -!!! example - ```yaml - builder: - libraryPreload: - excludes: - - "my/lib/thirdparty/" - - "!my/lib/thirdparty/NotExcluded.js" - ``` +::: tip Info +This configuration is available since UI5 CLI [`v2.10.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.10.0) +and applies only to projects defining [Specification Version](#specification-versions) +2.3 or higher. +::: + +> [!IMPORTANT] Example +>```yaml +>builder: +> libraryPreload: +> excludes: +> - "my/lib/thirdparty/" +> - "!my/lib/thirdparty/NotExcluded.js" +>``` + List of modules declared as glob patterns (resource name patterns) that are excluded from `library-preload.js` bundle. Similarly to the use of a single `*` or double `**` asterisk, a pattern ending with a slash `/` denotes an arbitrary number of characters or folder names. Re-includes have to be marked with a leading exclamation mark `!`. The order of filters is relevant; a later inclusion overrides an earlier exclusion, and vice versa. Note that patterns are always applied relative to the project's virtual source directory `/resources/`. Re-includes must start with the library's namespace. ### Custom Tasks -!!! example - ```yaml - builder: - customTasks: - - name: custom-task-1 - beforeTask: replaceCopyright - configuration: - some-key: some value - - name: custom-task-2 - afterTask: custom-task-1 - configuration: - color: blue - ``` +> [!IMPORTANT] Example +> +>```yaml +>builder: +> customTasks: +> - name: custom-task-1 +> beforeTask: replaceCopyright +> configuration: +> some-key: some value +> - name: custom-task-2 +> afterTask: custom-task-1 +> configuration: +> color: blue +>``` You can define custom build tasks that will be executed for the project. Please refer to the [Custom Tasks Documentation](./extensibility/CustomTasks.md) for a detailed explanation and examples of the build extensibility. @@ -537,13 +546,14 @@ Optionally, arbitrary `configuration` can be passed to the custom task. ### JSDoc -!!! example - ```yaml - builder: - jsdoc: - excludes: - - "some/project/name/thirdparty/**" - ``` +> [!IMPORTANT] Example +> +>```yaml +>builder: +> jsdoc: +> excludes: +> - "some/project/name/thirdparty/**" +>``` You can exclude the resources of a project from the JSDoc build process using a list of glob patterns. Matching resources will be ignored by the JSDoc build task. @@ -553,22 +563,23 @@ These excludes are applied *before* any general builder excludes that have been ### Include Dependencies -!!! info - This configuration is available since UI5 CLI [`v2.12.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.12.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.5 or higher. - -!!! example - ```yaml - builder: - settings: - includeDependency: - - shimmed.thirdparty.library - includeDependencyRegExp: - - ^com\.namespace - includeDependencyTree: - - sap.m - ``` +::: tip Info +This configuration is available since UI5 CLI [`v2.12.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.12.0) +and applies only to projects defining [Specification Version](#specification-versions) +2.5 or higher. +::: + +> [!IMPORTANT] Example +>```yaml +>builder: +> settings: +> includeDependency: +> - shimmed.thirdparty.library +> includeDependencyRegExp: +> - ^com\.namespace +> includeDependencyTree: +> - sap.m +>``` You can include certain dependencies into the build process using the `includeDependency` builder setting. By using `includeDependencyRegExp`, a regular expression can be used, for example to specify a namespace to dynamically select a group of dependencies that have to be included into the build result. By using `includeDependencyTree`, a selected dependency including all of its sub-dependencies is used. @@ -582,29 +593,30 @@ The project's `ui5.yaml` file can contain a list of modules declared as glob pat Note that patterns are always applied relative to the project's virtual source directory `/resources/`. -!!! info - This configuration is available since UI5 CLI [`v2.14.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.14.0) - and applies only to projects defining [Specification Version](#specification-versions) - 2.6 or higher. - -!!! example - ```yaml - builder: - minification: - excludes: - - "my/lib/thirdparty/" - - "!my/lib/thirdparty/NotExcluded.js" - ``` +::: tip Info +This configuration is available since UI5 CLI [`v2.14.0`](https://github.com/SAP/ui5-cli/releases/tag/v2.14.0) +and applies only to projects defining [Specification Version](#specification-versions) +2.6 or higher. +::: + +> [!IMPORTANT] Example +>```yaml +>builder: +> minification: +> excludes: +> - "my/lib/thirdparty/" +> - "!my/lib/thirdparty/NotExcluded.js" +>``` ## Server Configuration -!!! example - ```yaml - server: - settings: - httpPort: 1337 - httpsPort: 1443 - ``` +> [!IMPORTANT] Example +>```yaml +>server: +> settings: +> httpPort: 1337 +> httpsPort: 1443 +>``` By default, UI5 Tooling will serve applications using Port `8080`. When running in HTTP/2 or HTTPS mode, Port `8443` will be used. @@ -616,30 +628,30 @@ The default and configured server ports can always be overwritten with the CLI p ## Extension Configuration -!!! example - ```yaml - specVersion: "4.0" - type: application - metadata: - name: my.application - --- - specVersion: "4.0" - kind: extension - type: project-shim - metadata: - name: my.application.thirdparty - shims: - configurations: - lodash: - specVersion: "4.0" - type: module - metadata: - name: lodash - resources: - configuration: - paths: - /resources/my/application/thirdparty/: "" - ``` +> [!IMPORTANT] Example +>```yaml +>specVersion: "4.0" +>type: application +>metadata: +> name: my.application +>--- +>specVersion: "4.0" +>kind: extension +>type: project-shim +>metadata: +> name: my.application.thirdparty +>shims: +> configurations: +> lodash: +> specVersion: "4.0" +> type: module +> metadata: +> name: lodash +> resources: +> configuration: +> paths: +> /resources/my/application/thirdparty/: "" +>``` Extensions configuration can be added to any projects `ui5.yaml`. For better readability, it should to be located *after* the projects configuration, separated by [three dashes](https://yaml.org/spec/1.2/spec.html#id2760395) "`---`". @@ -648,41 +660,42 @@ In cases where an extension shall be reused across multiple projects you can mak Extensions can be identified by the `kind: extension` configuration. Note that if no `kind` configuration is given, [`project`](#project-configuration) is assumed. ### Available Extensions -- [Custom Tasks](./extensibility/CustomTasks.md) -- [Custom Server Middleware](./extensibility/CustomServerMiddleware.md) + +- [Custom Tasks](./extensibility/CustomTasks.md) + +- [Custom Server Middleware](./extensibility/CustomServerMiddleware.md) - [Project Shims](./extensibility/ProjectShims.md) ## Custom Bundling - -!!! example - ```yaml - builder: - bundles: - - bundleDefinition: - name: "sap-ui-custom.js" - sections: - - mode: raw - filters: - - ui5loader-autoconfig.js - resolve: true - sort: true - bundleOptions: - optimize: true - - bundleDefinition: - name: "app.js" - sections: - - mode: preload - filters: - - some/app/Component.js - resolve: true - sort: true - - mode: provided - filters: - - ui5loader-autoconfig.js - resolve: true - bundleOptions: - optimize: true - ``` +> [!IMPORTANT] Example +>```yaml +>builder: +> bundles: +> - bundleDefinition: +> name: "sap-ui-custom.js" +> sections: +> - mode: raw +> filters: +> - ui5loader-autoconfig.js +> resolve: true +> sort: true +> bundleOptions: +> optimize: true +> - bundleDefinition: +> name: "app.js" +> sections: +> - mode: preload +> filters: +> - some/app/Component.js +> resolve: true +> sort: true +> - mode: provided +> filters: +> - ui5loader-autoconfig.js +> resolve: true +> bundleOptions: +> optimize: true +>``` Custom bundles can be defined in the `ui5.yaml`. Within the `builder/bundles` configuration a list of `bundleDefinitions` can be described. @@ -693,9 +706,11 @@ Custom bundles can be defined in the `ui5.yaml`. Within the `builder/bundles` co A list of bundle definitions. A `bundleDefinition` contains of the following options: - `name`: The module bundle name + - `defaultFileTypes`: List of default file types which should be included in the bundle. Defaults to: `.js`, `.control.xml`, `.fragment.html`, `.fragment.json`, `.fragment.xml`, `.view.html`, `.view.json` and `.view.xml` - `sections`: A list of module bundle definition sections. Each section specifies an embedding technology (see [API-Reference](https://sap.github.io/ui5-tooling/v4/api/module-@ui5_builder_processors_bundlers_moduleBundler.html#~ModuleBundleDefinition)) and lists the resources that should be in- or excluded from the section. - `mode`: The embedding technology (e.g. provided, raw, preload, bundleInfo, depCache, require) + - `filters`: List of modules declared as glob patterns (resource name patterns) that are in- or excluded. Similarly to the use of a single `*` or double `**` asterisk, a pattern ending with a slash `/` denotes an arbitrary number of characters or folder names. Excludes have to be marked with a leading exclamation mark `!`. The order of filters is relevant; a later inclusion overrides an earlier exclusion, and vice versa. - `resolve`: Setting resolve to `true` will also include all (transitive) dependencies of the files - `resolveConditional`: Whether conditional dependencies of modules should be resolved and added to the module set for this section. By default set to `false` @@ -703,14 +718,15 @@ A list of bundle definitions. A `bundleDefinition` contains of the following opt - `renderer`: Whether renderers for controls should be added to the module set. By default set to `false` - `sort`: By default, modules are sorted by their dependencies. The sorting can be suppressed by setting the option to `false` - `async` (only available if `mode` equals `require`): Specifies whether the `require` section of the module should use an asynchronous API. When set to `true`, the modules are loaded using `sap.ui.require`. When set to `false`, modules are loaded using `sap.ui.requireSync`, which is not available in UI5 2.x. - - Projects defining [Specification Version](#specification-versions) 4.0 and higher: Defaults to `true` - - Projects defining [Specification Version](#specification-versions) lower than 4.0: Behaves like `false` but can't be configured + - Projects defining [Specification Version](#/docs/Configuration#specification-versions) 4.0 and higher: Defaults to `true` + - Projects defining [Specification Version](#/docs/Configuration#specification-versions) lower than 4.0: Behaves like `false` but can't be configured **bundleOptions** - `optimize`: If set to `true`, the module bundle gets minified - - Projects defining [Specification Version](#specification-versions) 3.0 and higher: Defaults to `true` - - Projects defining [Specification Version](#specification-versions) lower than 3.0: Defaults to `false` + + - Projects defining [Specification Version](/docs/Configuration##specification-versions) 3.0 and higher: Defaults to `true` + - Projects defining [Specification Version](#/docs/Configuration#specification-versions) lower than 3.0: Defaults to `false` - `decorateBootstrapModule`: By default set to `false`. If set to `true`, the module will be decorated with an optimization marker - `addTryCatchRestartWrapper`: By default set to `false`. If set to `true`, bootable module bundles gets wrapped with a try/catch to filter "Restart" errors - `numberOfParts`: By default set to `1`. The number of parts into which a module bundle should be splitted @@ -758,8 +774,9 @@ Version | UI5 CLI Release **Breaking changes:** -- Removed bundle option [`usePredefineCalls`](#properties). UI5 CLI v4.0.0 and above will always use predefine calls in bundles, making this option obsolete. -- Adds new a new option `async` for `bundleDefinition`-section configuration, see [Configuration: `bundleDefinition.sections`](../pages/Configuration.md#properties) for details. +- Removed bundle option [`usePredefineCalls`](/docs/Configuration##properties). UI5 CLI v4.0.0 and above will always use predefine calls in bundles, making this option obsolete. + +- Adds new a new option `async` for `bundleDefinition`-section configuration, see [Configuration: `bundleDefinition.sections`](/docs/Configuration##properties) for details. Specification Version 4.0 projects are supported by [UI5 CLI](https://github.com/SAP/ui5-cli) v4.0.0 and above. @@ -786,6 +803,7 @@ Specification Version 3.1 projects are supported by [UI5 CLI](https://github.com **Breaking changes:** - The `metadata.name` property is now restricted to contain only certain characters and no uppercase letters. See [`name`](#name) for details + - [bundleOptions](#custom-bundling) has been modified: * `debugMode` has been removed * `optimize` now always defaults to `true` [#685](https://github.com/SAP/ui5-builder/pull/685) diff --git a/docs/ESSupport.md b/docs/ESSupport.md new file mode 100644 index 0000000000..cdf6c85677 --- /dev/null +++ b/docs/ESSupport.md @@ -0,0 +1,551 @@ + +# ECMAScript Support + +UI5 Tooling offers general support for `ES2023` ECMAScript features. While a `ui5 build` is executed, UI5 Tooling analyses a project's code. Depending on the project type, you have to consider some restrictions regarding the usage of certain ECMAScript syntax. + +| UI5 Tooling Version | Supported ECMAScript Version | Note | +|-------------------- |----------------------------- | ---- | +| v3.11+ | ECMAScript 2023 | | +| v3.0+ | ECMAScript 2022 | | +| v2.0+ | ECMAScript 2009/ES5 | Note that code up to ECMAScript 2020 can be parsed, however required code analysis might not work correctly for specific language features | + +The following section describes all restrictions grouped by the kind of ECMAScript language feature. To get more insights into the code analysing executed by UI5 Tooling check out [Code Analysis](./CodeAnalysis.md). + +## Language Features with Restrictions + +The following sections describe the restrictions grouped by the ECMAScript language feature. + +### JavaScript modules + +In general, UI5 Tooling only analyzes **JavaScript** files of type `script`. [JavaScript Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) are not analyzed. + +UI5 Tooling and the UI5 Runtime does not support the usage of `export` and `import` of JavaScript Modules. Therefore, `sap.ui.define` has to be used. + + +::: code-group +```javascript [Supported] +sap.ui.define([ + "ModuleA", + "ModuleB" +], function(ModuleA, ModuleB) { + return ModuleA.extend("ModuleC", {}); +}); +``` + +```javascript [Not Supported] {1,2,3} +import ModuleA from "ModuleA"; +import ModuleB from "ModuleB"; +export default class ModuleC extends ModuleA {}; +``` +::: +### Template Literal + +[Template Literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) without an expressions can be used in all places where string literals can be used. However, since UI5 Tooling will attempt a static code analysis for certain calls to UI5 API, Template Literals with one or more expressions (e.g. `Hello ${planets[2]}`) can't be used in the scenarios described below. + +#### Template Literal in `sap.ui.define` or `sap.ui.require` + +Template Literals with one or more expressions inside a `sap.ui.define` or `sap.ui.require` call are not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + `ModuleA`, + `ModuleB` +], function(ModuleA, ModuleB) { +}); +``` +```javascript [Not Supported] {4} +const i = `B`; +sap.ui.define([ + `ModuleA`, + `Module${i}` +], function(ModuleA, ModuleB) { +}); +``` +::: +The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. + +#### Template Literal in Smart Template Declaration + +When declaring a **Smart Template** using a **Template Literal** with one or more expressions in the name of the **Smart Template** is not supported. + +::: code-group +```javascript [Supported] +sap.ui.define([ + `sap/suite/ui/generic/template/lib/TemplateAssembler` +], function(TemplateAssembler) { + return TemplateAssembler.getTemplateComponent(getMethods, + `sap.suite.ui.generic.templates.Page.Component`, { + metadata: { + properties: { + templateName: { + type: `string`, + defaultValue: `sap.suite.ui.generic.templates.Page.view.Page` + } + }, + manifest: `json` + } + } + ); +}); +``` +```javascript [Not Supported] {6} +sap.ui.define([ + `sap/suite/ui/generic/template/lib/TemplateAssembler` +], function(TemplateAssembler) { + const name = `Component`; + return TemplateAssembler.getTemplateComponent(getMethods, + `sap.suite.ui.generic.templates.Page.${name}`, { + metadata: { + properties: { + templateName: { + type: `string`, + defaultValue: `sap.suite.ui.generic.templates.Page.view.Page` + } + }, + manifest: `json` + } + } + ); +}); +``` +::: +#### Template Literal in XMLComposite Declaration + +The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. + +Declaring an **XMLComposite** control using a **Template Literal** with one or more expressions in the name, is not supported. + + +::: code-group + +```javascript [Supported] +sap.ui.define([ + `sap/ui/core/XMLComposite` +], function(XMLComposite) { + return XMLComposite.extend(`composites.MyComposite`, {} +}); +``` +```javascript [Not Supported] {5} +sap.ui.define([ + `sap/ui/core/XMLComposite` +], function(XMLComposite) { + const name = `MyComposite`; + return XMLComposite.extend(`composites.${name}`, {}); +}); +``` +::: +#### Template Literal in sap/ui/core/Core#initLibrary Call + +A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use a **Template Literal** with one or more expressions for the library name. + +::: code-group +```javascript [Supported] +sap.ui.getCore().initLibrary({ + name: `my.lib` +}); +``` +```javascript [Not Supported] {3} +const libraryName = `lib`; +sap.ui.getCore().initLibrary({ + name: `my.${libraryName}` +}); +``` +::: +#### Reserved Variable Names in a Template Literal + +While UI5 Tooling performs a build placeholders are replaced with a values offered by the build. For example `${version}` is replaced with the actual version defined in the package.json of the project. Therefore it is required to not use any **Template Literal** where any expression contains variable with following names: + +- `version` +- `project.version` +- `buildtime` +- `copyright` + +::: code-group + +```javascript [Supported] +const myVersion = `1.2`; +const transformedVersion `v${myVersion}` +``` +```javascript [Not Supported] {3} +const version = `1.2`; +const transformedVersion `v${version}` +``` +::: +UI5 Tooling searches for the exact match of `${version}`, so with adding whitespaces before and after the variable name `${ version }` UI5 Tooling won't replace this occurence. This can be enforced by the dedicated ESLint config [template-curly-spacing](https://eslint.org/docs/latest/rules/template-curly-spacing) with option `always`. + +### Spread Element + +A [Spread Element](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) can be used in all places, except the following. + +#### Spread Element in `sap.ui.define` or `sap.ui.require` + +A **Spread Element** as a parameter in a `sap.ui.define` or `sap.ui.require` call is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "ModuleA", + "ModuleB" +], function(ModuleA, ModuleB) { +}); +``` + + +```javascript [Not Supported] {3} +const dependencies = ["ModuleA", "ModuleB"]; +sap.ui.define([ + ...dependencies +], function(ModuleA, ModuleB) { +}); +``` +::: +The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. + +#### Spread Element in Smart Template Declaration + +When declaring a **Smart Template**, the usage of a **Spread Element** in the configuration is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "sap/suite/ui/generic/template/lib/TemplateAssembler" +], function(TemplateAssembler) { + return TemplateAssembler.getTemplateComponent(getMethods, + "sap.suite.ui.generic.templates.Page.Component", { + metadata: { + properties: { + templateName: { + type: "string", + defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" + } + }, + manifest: "json" + } + } + ); +}); +``` + + +```javascript [Not Supported] {6} +sap.ui.define([ + "sap/suite/ui/generic/template/lib/TemplateAssembler" +], function(TemplateAssembler) { + const myTemplate = { + templateName: { + type: "string", + defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" + } + }; + return TemplateAssembler.getTemplateComponent(getMethods, + "sap.suite.ui.generic.templates.Page.Component", { + metadata: { + properties: { + ...myTemplate + } + manifest: "json" + } + } + ); +}); +``` +::: + +#### Spread Element in XMLComposite Declaration + +The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. + +When declaring an **XMLComposite**, the usage of a **Spread Element** in the configuration is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + return XMLComposite.extend("composites.MyComposite", { + fragment: "composites.custom.MyComposite" + } +}); +``` + + +```javascript [Not Supported] {5} +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + const myXMLComposite = { + fragment: "composites.custom.MyComposite" + }; + return XMLComposite.extend(`composites.MyComposite`, { + ...myXMLComposite + }); +}); +``` +::: +#### Spread Element in sap/ui/core/Core#initLibrary Call + +A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use a **Spread Element**. + +::: code-group + +```javascript [Supported] +sap.ui.getCore().initLibrary({ + name: "my.lib" +}); +``` + + +```javascript [Not Supported] {5} +const mylib = { + name: "my.lib" +}; +sap.ui.getCore().initLibrary({ + ...mylib +}); +``` +::: + +### Object Expression + +An **Object Expression** can be used in all places except in following places. + +#### Object Expression in `sap.ui.define` or `sap.ui.require` + +An **Object Expression** as a parameter in a `sap.ui.define` or `sap.ui.require` call is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "Bar" +], function(Bar){ +}); +``` + + +```javascript [Not Supported] {3} +const dependency = "Bar"; +sap.ui.define([ + dependency +], function(Bar){ +}); +``` +::: + +The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. + +#### Object Expression in Smart Template Declaration + +When declaring a **Smart Template**, the usage of an **Object Expression** in the configuration is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "sap/suite/ui/generic/template/lib/TemplateAssembler" +], function(TemplateAssembler) { + return TemplateAssembler.getTemplateComponent(getMethods, + "sap.suite.ui.generic.templates.Page.Component", { + metadata: { + properties: { + templateName: { + type: "string", + defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" + } + }, + manifest: "json" + } + } + ); +}); +``` + + +```javascript [Not Supported] {9} +sap.ui.define([ + "sap/suite/ui/generic/template/lib/TemplateAssembler" +], function(TemplateAssembler) { + const key = "templateName" + return TemplateAssembler.getTemplateComponent(getMethods, + `sap.suite.ui.generic.templates.Page.${name}`, { + metadata: { + properties: { + [key]: { + type: "string", + defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" + } + } + manifest: "json" + } + } + ); +}); +``` +::: +#### Object Expression in XMLComposite Declaration + +The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. + +When declaring an **XMLComposite**, the usage of an **Object Expression** in the configuration is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + return XMLComposite.extend("composites.MyComposite", { + fragment: "composites.custom.MyComposite" + } +}); +``` + + +```javascript [Not Supported] {6} +sap.ui.define([ + "sap/ui/core/XMLComposite" +], function(XMLComposite) { + const key = "fragment"; + return XMLComposite.extend("composites.MyComposite", { + [key]: "composites.custom.MyComposite" + }); +}); +``` +::: +#### Object Expression in sap/ui/core/Core#initLibrary Call + +A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use an **Object Expression**. + +::: code-group + +```javascript [Supported] +sap.ui.getCore().initLibrary({ + name: "my.lib" +}); +``` + + + +```javascript [Not Supported] {3} +const key = "name"; +sap.ui.getCore().initLibrary({ + [key]: "my.lib" +}); +``` +::: +### Computed Property + +A **Computed Property** can be used in all places except in following places. + +#### Computed Property when using `extend` + +One or more **Computed Property** as a parameter in an UI5 Module `extend` call is not supported. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "Bar" +], function(Bar){ + return Bar.extend("my.Bar" {}); +}); +``` + +```javascript [Not Supported] +const name = "my"; +sap.ui.define([ + "Bar" +], function(Bar){ + return Bar.extend(name + ".Bar", {}); +}); +``` +::: + +#### Computed Properties in sap/ui/core/Core#initLibrary Call + +A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use an **Computed Property**. + +::: code-group + +```javascript [Supported] +sap.ui.getCore().initLibrary({ + name: "my.lib" +}); +``` + + +```javascript [Not Supported] {3} +const name = "my"; +sap.ui.getCore().initLibrary({ + name: name + ".lib" +}); +``` +::: + +### Class Declaration + +If you want to generate a JSDoc build of your project and using a **Class Declaration** the class declaration should not be returned directly. Declare the class and return the class in a separate statement. If not JSDoc treats the the class declaration as a return statement and does not recognize any JSDoc if such is provided right above the class declaration. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "Bar" +], function(Bar){ + /** + * JSDoc block here + */ + class Foo extends Bar { + make () {} + } + return Foo; +}); +``` + + +```javascript [Not Supported] {7} +sap.ui.define([ + "Bar" +], function(Bar){ + /** + * JSDoc block here + */ + return class Foo extends Bar { + make () {} + } +}); +``` +::: + +### Arrow Function Expression + +If you want to generate a JSDoc build of your project and use an **Arrow Function Expression** the JSDoc has to be written above the arrow function and not above the `sap.ui.define/sap.ui.require` command. + +::: code-group + +```javascript [Supported] +sap.ui.define([ + "Bar" +], +/** + * JSDoc block here + */ +(Bar) => Bar.extends("Foo", { +})); +``` + + +```javascript [Not Supported] {1,2,3} +/** + * JSDoc block here + */ +sap.ui.define([ + "Bar" +], (Bar) => Bar.extends("Foo", { +})); +``` diff --git a/docs/pages/FAQ.md b/docs/FAQ.md similarity index 100% rename from docs/pages/FAQ.md rename to docs/FAQ.md diff --git a/docs/pages/FileSystem.md b/docs/FileSystem.md similarity index 96% rename from docs/pages/FileSystem.md rename to docs/FileSystem.md index f24281b8cb..7249362ee8 100644 --- a/docs/pages/FileSystem.md +++ b/docs/FileSystem.md @@ -2,7 +2,7 @@ The [UI5 FS](https://github.com/SAP/ui5-fs) provides a UI5-specific file system abstraction. -[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/){: .md-button .sap-icon-initiative } +[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/) ## Overview @@ -27,6 +27,7 @@ The [File System Adapter](https://sap.github.io/ui5-tooling/v4/api/@ui5_fs_adapt Both adapters provide APIs to retrieve and persist [Resources](#resource), namely - to retrieve a single resource by its virtual path use `byPath()`, + - to retrieve many resources based on patterns use `byGlob()`, - to persist a single resource use `write()`. @@ -38,6 +39,7 @@ Reader collections allow grouped access to multiple adapters, which might even b They implement the same API for **retrieving** resources as adapters (`byPath` and `byGlob`). Multiple flavors exist: * [ReaderCollection](https://sap.github.io/ui5-tooling/v4/api/@ui5_fs_ReaderCollection.html): The most basic collection. Allows parallel read access to multiple readers (i.e. adapters or collections) + * [ReaderCollectionPrioritized](https://sap.github.io/ui5-tooling/v4/api/@ui5_fs_ReaderCollectionPrioritized.html): Contains a list of readers which are searched in-order. This allows one reader to "overlay" resources of another * [DuplexCollection](https://sap.github.io/ui5-tooling/v4/api/@ui5_fs_DuplexCollection.html): Contains a single reader and a single "writer". It therefore also implements the Adapter API for **persisting** resources (`write()`). When retrieving resources, the writer is prioritized over the reader * [WriterCollection](https://sap.github.io/ui5-tooling/v4/api/@ui5_fs_WriterCollection.html): Contains a set of writers and a mapping for each of them. When writing a resource, the writer is chosen based on the resource's virtual path. diff --git a/docs/pages/GettingStarted.md b/docs/GettingStarted.md similarity index 81% rename from docs/pages/GettingStarted.md rename to docs/GettingStarted.md index 0f7d90177e..c234b4d719 100644 --- a/docs/pages/GettingStarted.md +++ b/docs/GettingStarted.md @@ -49,21 +49,23 @@ If your project is not set up for use with the UI5 Tooling yet, follow these ste 1. Define the framework you want to use - === "OpenUI5" - ```sh - ui5 use openui5@latest - ``` - === "SAPUI5" +::: code-group + + ``` sh [OpenUI5] + ui5 use openui5@latest + ``` - ```sh - ui5 use sapui5@latest - ``` + ```sh [SAPUI5] + ui5 use sapui5@latest + ``` + +::: - You can choose between the OpenUI5 and the SAPUI5 framework. + You can choose between the OpenUI5 and the SAPUI5 framework. - Don't know which one to choose? Check out our [documentation on the differences between OpenUI5 and SAPUI5](./FAQ.md##whats-the-difference-between-openui5-and-sapui5). + Don't know which one to choose? Check out our [documentation on the differences between OpenUI5 and SAPUI5](/docs/FAQ.html#what-s-the-difference-between-openui5-and-sapui5). 1. Add required libraries ```sh @@ -80,15 +82,15 @@ If your project is not set up for use with the UI5 Tooling yet, follow these ste ui5 serve ``` - !!! tip - Use `ui5 serve` to start a local development server and `ui5 build --all` to produce an optimized, static version of your project, which you can then deploy to your production environment. - - Find more information here: +::: tip Tip +Use `ui5 serve` to start a local development server and `ui5 build --all` to produce an optimized, static version of your project, which you can then deploy to your production environment. - - [Server](./Server.md) - - [Builder](./Builder.md) - - [CLI](./CLI.md) +Find more information here: + [Server](./Server.md) + [Builder](./Builder.md) + [CLI](./CLI.md) +::: 1. If you are using Git or similar version control, commit `package.json` and `ui5.yaml` to your repository. ```sh git add package.json ui5.yaml @@ -96,4 +98,5 @@ If your project is not set up for use with the UI5 Tooling yet, follow these ste ``` **Hooray! You can now use UI5 Tooling in your project!** -{: .sap-icon-ui5-after } + + diff --git a/docs/Guidelines.md b/docs/Guidelines.md deleted file mode 100644 index 9739695c09..0000000000 --- a/docs/Guidelines.md +++ /dev/null @@ -1,60 +0,0 @@ -# Development Conventions and Guidelines -## JavaScript Coding Guidelines -We enforce code style rules using [ESLint](https://eslint.org). Execute `npm run lint` to check your code for style issues. -You may also find an ESLint integration for your favorite IDE [here](https://eslint.org/docs/user-guide/integrations). - -## Testing -Unit testing is based on the [ava](https://github.com/avajs/ava) test-framework. You can run all tests using `npm test` (this is what our CI will do for all pull requests). - -During development, you might want to use `npm run unit` or `npm run unit-watch` (re-runs tests automatically after file changes) to quickly execute all unit tests and see whether your change just broke one of them. 😉 - -## Git Guidelines -### No Merge Commits -Please use [rebase instead of merge](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) to update a branch to the latest main. This helps keeping a clean commit history in the project. - -### Commit Message Style -#### Commit Summary -The commit summary is the first line of the commit message. - -- It should be **50-70 characters** long. -- It must be **prefixed** by `[FIX]`, `[FEATURE]` or `[INTERNAL]` accordingly, followed by the name of the component or module which was the main subject of the change. - + Use `[FIX]` for bugfixes. - + Use `[FEATURE]` for new features / enhancements. - + Use `[BREAKING]` for breaking / incompatible changes. - _**Note:** The commit body of a breaking change should also include a paragraph starting with `BREAKING CHANGE:`. - This paragraph will be highlighted in the changelog._ - + Use `[DEPENDENCY]` for dependency updates that should be mentioned in the changelog. - + Use `[INTERNAL]` for all other changes (e.g. refactorings, documentation, etc.). These changes will not be listed in the changelog. - + Exceptions are changes created by automated processes like releases or dependency updates -- It must not contain `[` or `]` anywhere but in the prefix. -- It shall be written in **imperative present tense** (as recommended by [Git](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project)) - + Examples: Instead of *"Adding tests for"* or *"I added tests for"* use *"Add tests for"* or *"Add feature xy"*. - -#### Commit Body -After the commit summary there should be an empty line followed by the commit body. - -- Describe the intention and reasoning of the change -- If a change fixes an issue reported on GitHub, add the following line to the commit message: - + `Fixes: #` (e.g. `Fixes: #42`) -- Breaking changes should include a paragraph starting with `BREAKING CHANGE:`. This paragraph will be highlighted in the changelog. - -#### Example -``` -[FIX] npm translator: Correct handling of devDependencies - -- devDevependencies should only be included in certain cases -- Was caused by a refactoring - -Fixes: #42 -Fixes: #45 -``` - -## Work on Release Branches -Major releases are typically prepared on dedicated branches like `next`. - -There are some things to be aware of when working on these branches. - -### Implementing Changes in Multiple Code Lines -While working on a new major release (e.g. `5.0.0`), any fixes or new features implemented on the **current** (main) code line (e.g. 4.x) should be cherry-picked as `[INTERNAL]` to the dedicated (pre-)release branch (typically `next`). This is to prevent changes declared as `[FEATURE]` or `[FIX]` from appearing in the changelog twice, which can be confusing since the new major version has not yet been released and should naturally contain any fixes or features released in any of the preceding releases. Listing them twice might confuse users. Note that our changelog is generated based on all tags of the repository, independent of the currently checked out branch (also see [git-chglog/issues/123](https://github.com/git-chglog/git-chglog/issues/123)). - -However, once a new major release becomes **current** (i.e. "main", not a pre-release), any changes applied to multiple code lines should be cherry picked with the original prefix, so that they appear for multiple versions in the changelog. diff --git a/docs/HomePage.md b/docs/HomePage.md new file mode 100644 index 0000000000..f42dc972fd --- /dev/null +++ b/docs/HomePage.md @@ -0,0 +1,131 @@ + +# UI5 Tooling + +An open and modular toolchain to develop state-of-the-art applications based on the [UI5](https://ui5.sap.com) framework. + +::: tip 🚀 New Release +**UI5 Tooling V4 is here 🎉** + +Read the announcement blog post: **[SAP Community: UI5 Tooling 4.0](https://community.sap.com/t5/technology-blogs-by-sap/ui5-tooling-4-0/ba-p/13769578)** + +And checkout the **[Migrate to v4](./updates/migrate-v4.md)** documentation. +::: +[**Get Started**](./GettingStarted.md) + +## Main Features + +### 💻 UI5 CLI + +*Also see the [UI5 CLI Documentation](./CLI.md)* + +```sh +# Global +npm install --global @ui5/cli + +# In your project +npm install --save-dev @ui5/cli +``` + +#### ⚙️ Project Setup + +Configure your project for use with UI5 Tooling. +*Also see the [Configuration Documentation](./Configuration.md)* + +``` +❯ ui5 init +Wrote ui5.yaml: + +specVersion: "4.0" +metadata: + name: my-app +type: application +``` + +#### 🚚 Dependency Management + +UI5 framework dependencies are managed by the tooling. All other dependencies are managed by your favorite node package manager. + +``` +❯ ui5 use SAPUI5@1.117.0 +Updated configuration written to ui5.yaml +This project is now using SAPUI5 version 1.117.0 + +❯ ui5 add sap.ui.core sap.m themelib_sap_fiori_3 +Updated configuration written to ui5.yaml +Added framework libraries sap.ui.core sap.m themelib_sap_fiori_3 as dependencies +``` + +#### 🏄 Development Server + +Start a local development server to work on your project. +*Also see the [Server Documentation](./Server.md)* + +``` +❯ ui5 serve +Server started +URL: http://localhost:8080 +``` + +#### 🛠 Build for Production + +Build an optimized version of your project. +*Also see the [Builder Documentation](./Builder.md)* + +``` bash +❯ ui5 build +info graph:helpers:ui5Framework Using OpenUI5 version: 1.117.0 +info ProjectBuilder Preparing build for project my-app +info ProjectBuilder Target directory: ./dist +info ProjectBuilder Cleaning target directory... +info Project 1 of 1: ❯ Building application project my-app... +info my-app › Running task escapeNonAsciiCharacters... +info my-app › Running task replaceCopyright... +info my-app › Running task replaceVersion... +info my-app › Running task minify... +info my-app › Running task generateFlexChangesBundle... +info my-app › Running task generateComponentPreload... +info ProjectBuilder Build succeeded in 296 ms +info ProjectBuilder Executing cleanup tasks... +``` + +### 🧪 Node.js API + +Most UI5 Tooling modules provide JavaScript APIs for direct consumption in other Node.js projects. +This allows you to rely on UI5 Tooling for UI5-specific build functionality and project handling, while creating your own tools to perfectly match the needs of your project. + +All available APIs are documented in the [UI5 Tooling API Reference](https://sap.github.io/ui5-tooling/v4/api/index.html). + +::: code-group + + +```js [ESM] +import {graphFromPackageDependencies} from "@ui5/project/graph"; + +async function buildApp(projectPath, destinationPath) { + const graph = await graphFromPackageDependencies({ + cwd: projectPath + }); + await graph.build({ + destPath: destinationPath, + selfContained: true, + excludedTasks: ["transformBootstrapHtml"], + includedDependencies: ["*"] + }); +} +``` +```js [CommonJS] +async function buildApp(projectPath, destinationPath) { + const {graphFromPackageDependencies} = + await import("@ui5/project/graph"); + const graph = await graphFromPackageDependencies({ + cwd: projectPath + }); + await graph.build({ + destPath: destinationPath, + selfContained: true, + excludedTasks: ["transformBootstrapHtml"], + includedDependencies: ["*"] + }); +} +``` +::: \ No newline at end of file diff --git a/docs/pages/OpenUI5.md b/docs/OpenUI5.md similarity index 90% rename from docs/pages/OpenUI5.md rename to docs/OpenUI5.md index 354d6c9a97..c9eaf02e9d 100644 --- a/docs/pages/OpenUI5.md +++ b/docs/OpenUI5.md @@ -6,20 +6,21 @@ Note that projects using the SAPUI5 framework can depend on projects using the O Please also refer to our documentation on the [differences between OpenUI5 and SAPUI5](./FAQ.md#whats-the-difference-between-openui5-and-sapui5). -!!! info - The minimum OpenUI5 version that can be consumed by UI5 Tooling is **1.52.5** +::: tip Info +The minimum OpenUI5 version that can be consumed by UI5 Tooling is **1.52.5** +::: ## Configuration Your project's `ui5.yaml` provides a configuration section dedicated to framework dependency handling. This configuration can be maintained by editing the file, or by using the UI5 CLI: -!!! example - Using the [UI5 CLI](./CLI.md): - ```sh - ui5 use openui5@latest - ui5 add sap.ui.core sap.m sap.ui.table themelib_sap_fiori_3 - ``` +> [!IMPORTANT] Example +>Using the [UI5 CLI](./CLI.md): +>```sh +>ui5 use openui5@latest +>ui5 add sap.ui.core sap.m sap.ui.table themelib_sap_fiori_3 +>``` **Example ui5.yaml of an application** ```yaml diff --git a/docs/pages/Overview.md b/docs/Overview.md similarity index 97% rename from docs/pages/Overview.md rename to docs/Overview.md index 5f65dbbb22..6e27f786ec 100644 --- a/docs/pages/Overview.md +++ b/docs/Overview.md @@ -9,8 +9,9 @@ UI5 Tooling differentiates between "framework dependencies" and "project depende **Framework dependencies** are generally libraries and themes provided by the SAP frameworks "OpenUI5" and "SAPUI5". UI5 Tooling will take care of downloading them and handling their versions for you. Please see the corresponding documentation on both options: -* [Working with **OpenUI5** Framework Dependencies](./OpenUI5.md) -* [Working with **SAPUI5** Framework Dependencies](./SAPUI5.md) +- [Working with **OpenUI5** Framework Dependencies](./OpenUI5.md) + +- [Working with **SAPUI5** Framework Dependencies](./SAPUI5.md) **Project dependencies** are all other libraries, custom themes, UI5 Tooling extensions or JavaScript modules your project depends on. In general these dependencies are maintained in the package.json of your project. See also: [FAQ: Why package.json? / Why npm?](./FAQ.md#why-packagejson-why-npm). @@ -41,7 +42,7 @@ In its `package.json`, `my-app` should already define a dependency to `my-reuse- In the `my-app` directory, create a new file named `ui5-workspace.yaml` with the following content: -```yaml title="ui5-workspace.yaml" +```yaml " specVersion: workspace/1.0 metadata: name: default diff --git a/docs/pages/Privacy.md b/docs/Privacy.md similarity index 100% rename from docs/pages/Privacy.md rename to docs/Privacy.md diff --git a/docs/pages/Project.md b/docs/Project.md similarity index 82% rename from docs/pages/Project.md rename to docs/Project.md index 8524c98317..4bb985667e 100644 --- a/docs/pages/Project.md +++ b/docs/Project.md @@ -43,25 +43,28 @@ In the table below you can find the available combinations of project type & out | Project Type / Requested Output Style | Resulting Style | |---|---| | **application** | | -| `Default` | Root project is written `Flat`-style. ^1^ | +| `Default` | Root project is written `Flat`-style. ¹ | | `Flat` | Same as `Default`. | -| `Namespace` | Root project is written `Namespace`-style (resources are prefixed with the project's namespace). ^1^ | +| `Namespace` | Root project is written `Namespace`-style (resources are prefixed with the project's namespace). ¹ | +||| | **library** | | -| `Default` | Root project is written `Namespace`-style. ^1^ | -| `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it). ^1^ | +| `Default` | Root project is written `Namespace`-style. ¹ | +| `Flat` | Root project is written `Flat`-style (without its namespace, logging warnings for resources outside of it). ¹ | | `Namespace` | Same as `Default`. | +||| | **theme-library** | | -| `Default` | Root project is written in the style of the sources (multiple namespaces). ^1^ | -| `Flat` | **Unsupported** ^2^ | -| `Namespace` | **Unsupported** ^2^ | +| `Default` | Root project is written in the style of the sources (multiple namespaces). ¹ | +| `Flat` | **Unsupported** ² | +| `Namespace` | **Unsupported** ² | +||| | **module** | | -| `Default` | Root project is written with the [configured paths](https://sap.github.io/ui5-tooling/stable/pages/Configuration/#available-path-mappings). ^1^ | -| `Flat` | **Unsupported** ^3^ | -| `Namespace` | **Unsupported** ^3^ | +| `Default` | Root project is written with the [configured paths](https://sap.github.io/ui5-tooling/stable/pages/Configuration/#available-path-mappings). ¹ | +| `Flat` | **Unsupported** ³ | +| `Namespace` | **Unsupported** ³ | -^1^ The Output Style is only applied to the root project's output folder structure. Any dependencies included in the build would retain their `Default` output style. -^2^ Theme libraries in most cases have more than one namespace. -^3^ Modules have explicit path mappings configured and no namespace concept. +¹ The Output Style is only applied to the root project's output folder structure. Any dependencies included in the build would retain their `Default` output style. +² Theme libraries in most cases have more than one namespace. +³ Modules have explicit path mappings configured and no namespace concept. -[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_ProjectBuilder.html){: .md-button .sap-icon-initiative } +[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_ProjectBuilder.html) diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..7bd38eaf9c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,50 @@ +![UI5 logo](images/UI5_logo_wide.png) + +# UI5 Tooling + +> An open and modular toolchain to develop state-of-the-art applications based on the [UI5](https://ui5.sap.com) framework. + +[![REUSE status](https://api.reuse.software/badge/github.com/SAP/ui5-tooling)](https://api.reuse.software/info/github.com/SAP/ui5-tooling) +[![OpenUI5 Community Slack (#tooling channel)](https://img.shields.io/badge/slack-join-44cc11.svg)](https://ui5-slack-invite.cfapps.eu10.hana.ondemand.com) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) + +> [UI5 Tooling v4](https://sap.github.io/ui5-tooling/v4) is the latest and stable version 🎉 +> +> [UI5 Tooling v3](https://sap.github.io/ui5-tooling/v3) is a stable version and in maintenance mode 🚢 +> +> [UI5 Tooling v2](https://sap.github.io/ui5-tooling/v2) has been deprecated 🚫 +> +> Please migrate your projects to [UI5 Tooling v3](https://sap.github.io/ui5-tooling/v3/updates/migrate-v3/)! + +## Resources + +- [Documentation](https://sap.github.io/ui5-tooling/v3/) +- [API Reference](https://sap.github.io/ui5-tooling/v3/api/) +- [CLI Documentation](https://sap.github.io/ui5-tooling/v3/pages/CLI/) +- [Project Configuration](https://sap.github.io/ui5-tooling/v3/pages/Configuration/) +- 🎬 [UI5con@SAP 2020 Talk](https://www.youtube.com/watch?v=8IHoVJLKN34) +- 🎬 [UI5con@SAP 2018 Talk](https://www.youtube.com/watch?v=iQ07oe26y_k) +- [Contribution Guidelines](https://github.com/SAP/ui5-tooling/blob/main/CONTRIBUTING.md) +- [Roadmap](https://github.com/SAP/ui5-tooling/issues/701) + +## Modules + +UI5 Tooling consists of multiple modules. Each one is managed in a separate repository: + +- [ui5-cli](https://github.com/SAP/ui5-cli): UI5 Command Line Interface, utilizing all of the following modules +- [ui5-project](https://github.com/SAP/ui5-project): Modules for building a UI5 project's dependency tree, including configuration +- [ui5-server](https://github.com/SAP/ui5-server): Modules for running a UI5 development server +- [ui5-builder](https://github.com/SAP/ui5-builder): Modules for building UI5 projects +- [ui5-fs](https://github.com/SAP/ui5-fs): UI5 specific file system abstraction +- [ui5-logger](https://github.com/SAP/ui5-logger): Internal logging module + +**Usage Overview** *(arrows indicate dependencies)* +![Module Overview](images/Module_overview.png) + +## Contributing + +Please check our [Contribution Guidelines](https://github.com/SAP/ui5-tooling/blob/main/CONTRIBUTING.md). + +## Support + +Please follow our [Contribution Guidelines](https://github.com/SAP/ui5-tooling/blob/main/CONTRIBUTING.md#report-an-issue) on how to report an issue. Or chat with us in the [`#tooling`](https://openui5.slack.com/archives/C0A7QFN6B) channel of the [OpenUI5 Community Slack](https://ui5-slack-invite.cfapps.eu10.hana.ondemand.com). For public Q&A, use the [`ui5-tooling` tag on Stack Overflow](https://stackoverflow.com/questions/tagged/ui5-tooling). diff --git a/docs/pages/SAPUI5.md b/docs/SAPUI5.md similarity index 72% rename from docs/pages/SAPUI5.md rename to docs/SAPUI5.md index 5db362a6ff..e31463a46f 100644 --- a/docs/pages/SAPUI5.md +++ b/docs/SAPUI5.md @@ -1,17 +1,27 @@ # Consuming SAPUI5 Libraries -!!! info - Make sure you have installed the UI5 CLI in Version 2.0 or later: `npm install --global @ui5/cli` - The minimum version of SAPUI5 that can be consumed by UI5 Tooling as described below is **1.76.0.** - For lower versions, consider using the [CDN bootstrap](https://ui5.sap.com/#/topic/2d3eb2f322ea4a82983c1c62a33ec4ae) or a custom middleware like [ui5-middleware-simpleproxy](https://www.npmjs.com/package/ui5-middleware-simpleproxy). + +> [!TIP] Info +> Make sure you have installed the UI5 CLI in Version +> 2.0 or later: `npm install --global @ui5/cli` +> The minimum version of SAPUI5 that can be consumed +> by UI5 Tooling as described below is **1.76.0.** +> For lower versions, consider using the [CDN-bootstrap](https://ui5.sap.com/#/topic/2d3eb2f322ea4a82983c1c62a33ec4ae) or a custom +> middleware like [ui5-middleware-simpleproxy](https://www.npmjs.com/package/ui5-middleware-simpleproxy). + + + + + ## Overview SAPUI5 libraries are hosted on the public npm registry at `registry.npmjs.org`. However, you should not install them using node package managers such as npm. Let UI5 Tooling handle them instead by following this guide. -!!! note - For more background information also see the Blog Post ["UI5ers Buzz #49: The UI5 Tooling and SAPUI5 – The Next Step"](https://blogs.sap.com/2020/04/01/ui5ers-buzz-49-the-ui5-tooling-and-sapui5-the-next-step/) +::: info Note +For more background information also see the Blog Post ["UI5ers Buzz #49: The UI5 Tooling and SAPUI5 – The Next Step"](https://blogs.sap.com/2020/04/01/ui5ers-buzz-49-the-ui5-tooling-and-sapui5-the-next-step/) +::: ## Usage Since Version 2.0 of the UI5 CLI, it will automatically download all required framework dependencies of a project that have been listed in the corresponding `ui5.yaml` file. They will be cached in a `.ui5` directory located in the user's home directory. This happens transparently whenever you execute the `ui5 serve` or `ui5 build` commands. @@ -24,13 +34,13 @@ Your project's `ui5.yaml` provides a configuration section dedicated to framewor This configuration can be maintained by editing the file, or by using the UI5 CLI: -!!! example - Using the [UI5 CLI](./CLI.md): - ```sh - ui5 use sapui5@latest - ui5 add sap.ui.core sap.m sap.ui.comp themelib_sap_fiori_3 - ui5 add -D sap.ushell - ``` +> [!IMPORTANT] +>**Using the [UI5 CLI](./CLI.md):** +>```sh +>ui5 use sapui5@latest +>ui5 add sap.ui.core sap.m sap.ui.comp themelib_sap_fiori_3 +>ui5 add -D sap.ushell +>``` **Example ui5.yaml of an application** ```yaml diff --git a/docs/pages/Server.md b/docs/Server.md similarity index 93% rename from docs/pages/Server.md rename to docs/Server.md index a9d12f1ddb..2a778d0794 100644 --- a/docs/pages/Server.md +++ b/docs/Server.md @@ -2,7 +2,7 @@ The [UI5 Server](https://github.com/SAP/ui5-server) module provides server capabilities for local development of UI5 projects. -[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/module-@ui5_server.html){: .md-button .sap-icon-initiative } +[**API Reference**](https://sap.github.io/ui5-tooling/v4/api/module-@ui5_server.html) ## Standard Middleware @@ -73,5 +73,6 @@ When starting the UI5 Server in HTTPS- or HTTP/2 mode, for example by using UI5 Follow the given instructions and enter your password to install the generated certificate as trusted. You can find the generated certificate and corresponding private key under `.ui5/server` in your user's home directory. -!!! tip - If Chrome unintentionally redirects an HTTP-URL to HTTPS, you need to delete the HSTS mapping in [chrome://net-internals/#hsts](chrome://net-internals/#hsts) by entering the domain name (e.g. localhost) and pressing "delete". +::: tip +If Chrome unintentionally redirects an HTTP-URL to HTTPS, you need to delete the HSTS mapping in [chrome://net-internals/#hsts](chrome://net-internals/#hsts) by entering the domain name (e.g. localhost) and pressing "delete". +::: diff --git a/docs/pages/Troubleshooting.md b/docs/Troubleshooting.md similarity index 86% rename from docs/pages/Troubleshooting.md rename to docs/Troubleshooting.md index 960c8e1041..00871eb866 100644 --- a/docs/pages/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -50,9 +50,9 @@ UI5 + Karma: `cross-env UI5_LOG_LVL=verbose npm run karma` -!!! warning - The combination of the `UI5_LOG_LVL` environment variable with the `--log-level` CLI parameter might lead to unexpected results; they should be used interchangeably but not together. The CLI parameter takes precedence over the `UI5_LOG_LVL` environment variable. - +::: warning +The combination of the `UI5_LOG_LVL` environment variable with the `--log-level` CLI parameter might lead to unexpected results; they should be used interchangeably but not together. The CLI parameter takes precedence over the `UI5_LOG_LVL` environment variable. +::: ### Changing UI5 Tooling's Data Directory UI5 Tooling's data directory is by default at `~/.ui5`. It's the place where the framework artifacts are stored. @@ -60,9 +60,9 @@ In some cases and environments this is not a convenient location and the user ne The path to it can either be provided via environment variable or permanently set in the configuration. -!!! info - Paths are resolved relative to the current root project path (i.e. where the package.json is located). - +::: tip Info +Paths are resolved relative to the current root project path (i.e. where the package.json is located). +::: #### Environment variable `UI5_DATA_DIR` Unix: diff --git a/docs/pages/Workspace.md b/docs/Workspace.md similarity index 83% rename from docs/pages/Workspace.md rename to docs/Workspace.md index ad53d88676..8c76d8c2f2 100644 --- a/docs/pages/Workspace.md +++ b/docs/Workspace.md @@ -1,42 +1,45 @@ # UI5 Workspaces -!!! info - **UI5 Workspaces is a new feature available since UI5 CLI [`v3.0.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.0.0)** - -!!! example - ```yaml title="ui5-workspace.yaml" - specVersion: workspace/1.0 - metadata: - name: default - dependencyManagement: - resolutions: - - path: ../heavy.library - ``` +> [!TIP] Info +> **UI5 Workspaces is a new feature available since UI5 CLI [`v3.0.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.0.0)** + + +> [!IMPORTANT] Example +**ui5-workspace.yaml** +>```yaml +>yaml title="ui5-workspace.yaml" +>specVersion: workspace/1.0 +>metadata: +> name: default +>dependencyManagement: +> resolutions: +> - path: ../heavy.library +>``` ## General Concept UI5 Workspaces can be used to create a personalized local development environment for a UI5 project. They allow to use UI5 dependencies from local directories without the need to use the link features of package managers like npm. "UI5 dependencies" generally refers to projects that have a `ui5.yaml`. Workspaces are typically configured in a `ui5-workspace.yaml` file, located next to the project's `ui5.yaml`. The file can contain one or many workspace configurations, each separated by [three dashes](https://yaml.org/spec/1.2.2/#22-structures). For example: - -!!! example - ```yaml title="ui5-workspace.yaml" - specVersion: workspace/1.0 - metadata: - name: default - dependencyManagement: - resolutions: - - path: ../heavy.library - --- - specVersion: workspace/1.0 - metadata: - name: extended - dependencyManagement: - resolutions: - - path: ../heavy.library - - path: ../light.library - - path: ../test.library - ``` +> [!IMPORTANT] Example +> **ui5-workspace.yaml** +> ```yaml +>specVersion: workspace/1.0 +>metadata: +> name: default +>dependencyManagement: +> resolutions: +> - path: ../heavy.library +>--- +>specVersion: workspace/1.0 +>metadata: +> name: extended +>dependencyManagement: +> resolutions: +> - path: ../heavy.library +> - path: ../light.library +> - path: ../test.library +>``` If a workspace configuration named `default` exists, it will be used automatically; otherwise the workspace must be specified using the UI5 CLI parameter `--workspace`. @@ -53,12 +56,12 @@ specVersion: "workspace/1.0" ### Metadata -!!! example - ```yaml - specVersion: workspace/1.0 - metadata: - name: dolphin - ``` +> [!IMPORTANT] Example +>```yaml +>specVersion: workspace/1.0 +>metadata: +> name: dolphin +>``` #### name @@ -82,18 +85,18 @@ The `name` property must satisfy the following conditions. They are identical to ## Dependency Management UI5 Workspace configurations allow to influence the dependency resolution when working with a UI5 project. - -!!! example - ```yaml - specVersion: workspace/1.0 - metadata: - name: dolphin - dependencyManagement: - resolutions: - - path: ../light.library - - path: ../heavy.library - - path: ../test.library - ``` +> [!IMPORTANT] Example +> +>```yaml +>specVersion: workspace/1.0 +>metadata: +> name: dolphin +>dependencyManagement: +> resolutions: +> - path: ../light.library +> - path: ../heavy.library +> - path: ../test.library +>``` ### Resolutions diff --git a/docs/extensibility/CustomServerMiddleware.md b/docs/extensibility/CustomServerMiddleware.md new file mode 100644 index 0000000000..8c75238c55 --- /dev/null +++ b/docs/extensibility/CustomServerMiddleware.md @@ -0,0 +1,255 @@ +# Custom UI5 Server Middleware + +The UI5 Server Extensibility enables you to enhance the functionality of the UI5 Server. You may want to handle requests differently. For example add various headers to a response or parse data of a POST request in a specific way. For this you can plug custom middleware implementations into the internal [express](https://expressjs.com/) server of the UI5 Server module. + +The UI5 community already created many custom middleware packages which you can integrate into your project. They are often prefixed by `ui5-middleware-` to make them easily searchable in the [npm registry](https://www.npmjs.com/search?q=ui5-middleware-). + +Please note that custom middleware packages from third parties can not only modify how your project is served but also execute arbitrary code on your system. In fact, this is the case for all npm packages you install. Always act with the according care and follow best practices. + +## Configuration + +In a projects `ui5.yaml` file, you can define additional server middleware modules that will be executed when the request is received by the server. This configuration exclusively affects the server started in this project. Custom middleware configurations defined in any dependencies are ignored. + +A middleware may be executed before or after any other middleware. This can either be a [standard middleware](../Server.md#standard-middleware) or another custom middleware. + +### Example: Basic configuration + + +```yaml +# In this example configuration, two custom tasks are defined: 'babel' and 'render-markdown-files'. +specVersion: "4.0" +type: application +metadata: + name: my.application +server: + customMiddleware: + - name: myCustomMiddleware + mountPath: /myapp + afterMiddleware: compression + configuration: + debug: true +``` + +In the above example the middleware `compression` is already included as a standard middleware by the UI5 Server. When serving the application `my.application`, the server will call the custom middleware `myCustomMiddleware` after `compression`. + +There can be optional configuration parameters which are passed directly to the custom middleware implementation (see below). + +An optional mountPath for which the middleware function is invoked can be provided. It will be passed to the `app.use` call (see [express API reference](https://expressjs.com/en/4x/api.html#app.use)). + +### Execution order + +Note that middleware configurations are applied in the order they are defined. When referencing another custom middleware, it has to be defined *before* that reference. + +## Custom Middleware Extension + +A custom middleware extension consists of a `ui5.yaml` and a [custom middleware implementation](#custom-middleware-implementation). It can be a standalone module or part of an existing UI5 project. + +### Example: ui5.yaml + +```yaml +specVersion: "4.0" +kind: extension +type: server-middleware +metadata: + name: markdownHandler +middleware: + path: lib/middleware/markdownHandler.js +``` + +Custom middleware extensions can be **standalone modules** which are handled as dependencies. + +Alternatively you can implement a custom middleware extension as **part of your UI5 project**. +In that case, the configuration of the extension is part of your project configuration inside the `ui5.yaml` as shown below. + +The UI5 Server will detect the custom middleware configuration of the project and use the middleware on startup. + +### Example: Custom Middleware Extension defined in UI5 project + +```yaml +# Project configuration for the above example +specVersion: "4.0" +kind: project +type: application +metadata: + name: my.application +server: + customMiddleware: + - name: markdownHandler + beforeMiddleware: serveResources +--- +# Custom middleware extension as part of your project +specVersion: "4.0" +kind: extension +type: server-middleware +metadata: + name: markdownHandler +middleware: + path: lib/middleware/markdownHandler.js +``` + +## Custom Middleware Implementation + +A custom middleware implementation needs to return a function with the following signature: + +::: code-group + +```js [ESM] +/** + * Custom UI5 Server middleware API + * + * @param {object} parameters Parameters + * @param {@ui5/logger/Logger} parameters.log + * Logger instance for use in the custom middleware. + * This parameter is only provided to custom middleware + * extensions defining Specification Version 3.0 and later. + * @param {@ui5/server.middleware.MiddlewareUtil} parameters.middlewareUtil + * Specification version-dependent interface to a + * MiddlewareUtil instance. See the corresponding API reference for details: + * https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html + * @param {object} parameters.options Options + * @param {string} parameters.options.configuration + * Custom middleware configuration, as defined in the project's ui5.yaml + * @param {string} parameters.options.middlewareName + * Name of the custom middleware. + * This parameter is only provided to custom middleware extensions + * defining Specification Version 3.0 and later + * @param {object} parameters.resources Readers for accessing resources + * @param {module:@ui5/fs.AbstractReader} parameters.resources.all + * Reader to access resources of the root project and its dependencies + * @param {module:@ui5/fs.AbstractReader} parameters.resources.rootProject + * Reader to access resources of the root project + * @param {module:@ui5/fs.AbstractReader} parameters.resources.dependencies + * Reader to access resources of the project's dependencies. + * @returns {function} Middleware function to use + */ +export default function({log, middlewareUtil, options, resources}) { + return async function (req, res, next) { + // [...] + } +}; +``` +```js [CommonJS] +/** + * Custom UI5 Server middleware API + * + * @param {object} parameters Parameters + * @param {@ui5/logger/Logger} parameters.log + * Logger instance for use in the custom middleware. + * This parameter is only provided to custom middleware + * extensions defining Specification Version 3.0 and later. + * @param {@ui5/server.middleware.MiddlewareUtil} parameters.middlewareUtil + * Specification version-dependent interface to a + * MiddlewareUtil instance. See the corresponding API reference for details: + * https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html + * @param {object} parameters.options Options + * @param {string} parameters.options.configuration + * Custom middleware configuration, as defined in the project's ui5.yaml + * @param {string} parameters.options.middlewareName + * Name of the custom middleware. + * This parameter is only provided to custom middleware extensions + * defining Specification Version 3.0 and later + * @param {object} parameters.resources Readers for accessing resources + * @param {module:@ui5/fs.AbstractReader} parameters.resources.all + * Reader to access resources of the root project and its dependencies + * @param {module:@ui5/fs.AbstractReader} parameters.resources.rootProject + * Reader to access resources of the root project + * @param {module:@ui5/fs.AbstractReader} parameters.resources.dependencies + * Reader to access resources of the project's dependencies. + * @returns {function} Middleware function to use + */ +module.exports = function({log, middlewareUtil, options, resources}) { + return async function (req, res, next) { + // [...] + } +}; +``` +::: +### Example: lib/middleware/markdownHandler.(m)js + +::: code-group + +```js [ESM] + + +import MarkdownIt from "markdown-it";export default async function({log, middlewareUtil, options, resources}) { + const md = new MarkdownIt(); + return function (req, res, next) { + if (!req.path || !req.path.endsWith(".html")) { + // Do not handle non-HTML requests + next(); + return; + } + // Try to read a corresponding markdown file + resources.rootProject.byPath(req.path.replace(".html", ".md")).then(async (resource) => { + if (!resource) { + // No file found, hand over to next middleware + next(); + return; + } + log.info(`Rendering markdown for ${resource.getPath()}`); + const markdown = await resource.getBuffer(); + // Generate HTML from markdown string + const html = md.render(markdown.toString()); + res.type('.html'); + res.end(html); + }).catch((err) => { + next(err); + }); + } + }; +``` + + + + +```js [CommonJS] +module.exports = async function({log, middlewareUtil, options, resources}) { + const MarkdownIt = require("markdown-it"); + const md = new MarkdownIt(); + return function (req, res, next) { + if (!req.path || !req.path.endsWith(".html")) { + // Do not handle non-HTML requests + next(); + return; + } + // Try to read a corresponding markdown file + resources.rootProject.byPath(req.path.replace(".html", ".md")).then(async (resource) => { + if (!resource) { + // No file found, hand over to next middleware + next(); + return; + } + log.info(`Rendering markdown for ${resource.getPath()}`); + const markdown = await resource.getBuffer(); + // Generate HTML from markdown string + const html = md.render(markdown.toString()); + res.type('.html'); + res.end(html); + }).catch((err) => { + next(err); + }); + } +}; +``` +- [CommonJS example ](https://github.com/SAP/openui5-sample-app/tree/demo-server-middleware-extensibility-v3) +- [ESM example](https://github.com/SAP/openui5-sample-app/tree/demo-server-middleware-extensibility-v3-esm) +## Helper Class `MiddlewareUtil` + +Custom middleware defining [Specification Version](../Configuration.md#specification-versions) 2.0 or higher have access to an interface of a [MiddlewareUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html) instance. + +In this case, a `middlewareUtil` object is provided as a part of the custom middleware's [parameters](#custom-middleware-implementation). Depending on the specification version of the custom middleware, a set of helper functions is available to the implementation. The lowest required specification version for every function is listed in the [MiddlewareUtil API reference](https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html). + +## Integration with `karma-ui5` + +::: warning +The Karma project has been [deprecated](https://github.com/karma-runner/karma#karma-is-deprecated-and-is-not-accepting-new-features-or-general-bug-fixes) as of 2023 +::: +[`karma-ui5`](https://github.com/SAP/karma-ui5) is a plugin for the popular [Karma test runner](https://karma-runner.github.io/). Based on your [configuration](https://github.com/SAP/karma-ui5#url), it can fetch resources from a dedicated server or start an internal server using parts of UI5 Tooling. + +In the latter case, any custom middleware configured in the default `ui5.yaml` of the project will be used automatically. + +However, since Karma uses the [`connect`](https://github.com/senchalabs/connect) framework, as opposed to UI5 Tooling's [`express`](https://github.com/expressjs/express), custom middleware might not always work as expected. Compared to `connect`, the `express` framework provides a more versatile API to middleware. + +Therefore, if you plan to use custom middleware in an integrated scenario with `karma-ui5`, you must **restrict the middleware to using the [`connect`](https://github.com/senchalabs/connect) API only** to ensure compatibility. + +Alternatively, you can start a server with the usual `ui5 serve` command and [configure the corresponding URL](https://github.com/SAP/karma-ui5#url) for use by `karma-ui5`. diff --git a/docs/extensibility/CustomTasks.md b/docs/extensibility/CustomTasks.md new file mode 100644 index 0000000000..31c6c33fbc --- /dev/null +++ b/docs/extensibility/CustomTasks.md @@ -0,0 +1,454 @@ +# Custom UI5 Builder Tasks + +The UI5 Build Extensibility enables you to enhance the build process of any UI5 project. In addition to the [standard tasks](../Builder.md#standard-tasks), custom tasks can be created. + +The UI5 community already created many custom tasks which you can integrate into your project. They are often prefixed by `ui5-task-` to make them easily searchable in the [npm registry](https://www.npmjs.com/search?q=ui5-task-). + +Please note that custom tasks from third parties can not only modify your project but also execute arbitrary code on your system. In fact, this is the case for all npm packages you install. Always act with the according care and follow best practices. + +## Configuration + +You can configure your build process with additional build task. These custom tasks are defined in the project [configuration](../Configuration.md). + +To hook your custom tasks into the different build phases of a project, they need to reference other tasks to be executed before or after. This can be a [standard task](../Builder.md#standard-tasks) or another custom task. +Standard tasks that are disabled, even though they are not executed, can still be referenced by custom tasks, which will be performed in their designated position. + +In the below example, when building the library `my.library` the custom `babel` task will be executed before the standard task `generateComponentPreload`. +Another custom task called `render-markdown-files` is then executed immediately after the standard task `minify`. + +### Example: Basic configuration + +```yaml +# In this example configuration, two custom tasks are defined: 'babel' and 'render-markdown-files'. +specVersion: "4.0" +type: library +metadata: + name: my.library +builder: + customTasks: + - name: babel + beforeTask: generateComponentPreload + - name: render-markdown-files + afterTask: minify + configuration: + markdownStyle: + firstH1IsTitle: true +``` + +### Example: Connect multiple custom tasks + +You can also connect multiple custom tasks with each other. The order in the configuration is important in this case. You have to make sure that a task is defined *before* you reference it via `beforeTask` or `afterTask`. + +```yaml +# In this example, 'my-custom-task-2' gets executed after 'my-custom-task-1'. +specVersion: "4.0" +type: library +metadata: + name: my.library +builder: + customTasks: + - name: my-custom-task-1 + beforeTask: generateComponentPreload + - name: my-custom-task-2 + afterTask: my-custom-task-1 +``` + +## Custom Task Extension + +A custom task extension consists of a `ui5.yaml` and a [task implementation](#task-implementation). It can be a standalone module or part of an existing UI5 project. + +### Example: ui5.yaml + +```yaml +specVersion: "4.0" +kind: extension +type: task +metadata: + name: render-markdown-files +task: + path: lib/tasks/renderMarkdownFiles.js +``` + +Task extensions can be **standalone modules** which are handled as dependencies. + +Alternatively you can implement a task extension as **part of your UI5 project**. +In that case, the configuration of the extension is part of your project configuration inside the `ui5.yaml` as shown below. + +The task extension will then be automatically collected and processed during the processing of the project. + +### Example: Custom Task Extension defined in UI5 project + +```yaml +# Project configuration for the above example +specVersion: "4.0" +kind: project +type: library +metadata: + name: my.library +builder: + customTasks: + - name: render-markdown-files + afterTask: minify + configuration: + markdownStyle: + firstH1IsTitle: true +--- +# Task extension as part of your project +specVersion: "4.0" +kind: extension +type: task +metadata: + name: render-markdown-files +task: + path: lib/tasks/renderMarkdownFiles.js +``` + +## Task Implementation + +A custom task implementation needs to return a function with the following signature: + + +::: code-group +```js [ESM] +/** + * Custom task API + * + * @param {object} parameters + * + * @param {module:@ui5/fs.AbstractReader} parameters.dependencies + * Reader to access resources of the project's dependencies + * @param {@ui5/logger/Logger} parameters.log + * Logger instance for use in the custom task. + * This parameter is only available to custom task extensions + * defining Specification Version 3.0 and later. + * @param {object} parameters.options Options + * @param {string} parameters.options.projectName + * Name of the project currently being built + * @param {string} parameters.options.projectNamespace + * Namespace of the project currently being built + * @param {string} parameters.options.configuration + * Custom task configuration, as defined in the project's ui5.yaml + * @param {string} parameters.options.taskName + * Name of the custom task. + * This parameter is only provided to custom task extensions + * defining Specification Version 3.0 and later. + * @param {@ui5/builder.tasks.TaskUtil} parameters.taskUtil + * Specification Version-dependent interface to a TaskUtil instance. + * See the corresponding API reference for details: + * https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html + * @param {module:@ui5/fs.DuplexCollection} parameters.workspace + * Reader/Writer to access and modify resources of the + * project currently being built + * @returns {Promise} + * Promise resolving once the task has finished + */ +export default async function({dependencies, log, options, taskUtil,workspace}) { + // [...] +}; +``` + + + +```js [CommonJS] +/** + * Custom task API + * + * @param {object} parameters + * + * @param {module:@ui5/fs.AbstractReader} parameters.dependencies + * Reader to access resources of the project's dependencies + * @param {@ui5/logger/Logger} parameters.log + * Logger instance for use in the custom task. + * This parameter is only available to custom task extensions + * defining Specification Version 3.0 and later. + * @param {object} parameters.options Options + * @param {string} parameters.options.projectName + * Name of the project currently being built + * @param {string} parameters.options.projectNamespace + * Namespace of the project currently being built + * @param {string} parameters.options.configuration + * Custom task configuration, as defined in the project's ui5.yaml + * @param {string} parameters.options.taskName + * Name of the custom task. + * This parameter is only provided to custom task extensions + * defining Specification Version 3.0 and later. + * @param {@ui5/builder.tasks.TaskUtil} parameters.taskUtil + * Specification Version-dependent interface to a TaskUtil instance. + * See the corresponding API reference for details: + * https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html + * @param {module:@ui5/fs.DuplexCollection} parameters.workspace + * Reader/Writer to access and modify resources of the + * project currently being built + * @returns {Promise} + * Promise resolving once the task has finished + */ +module.exports = async function({dependencies, log, options, taskUtil,workspace}) { + // [...] +}; +``` +::: +### Required Dependencies + +::: tip Info +This functionality has been added with UI5 CLI [`v3.0.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.0.0) +::: +Custom tasks can export an optional callback function `determineRequiredDependencies` to control which dependency-resources are made available through the `dependencies`-reader that is provided to the task. By reducing the amount of required dependencies or by not requiring any, UI5 Tooling might be able to build a project faster. + +Before executing a task, UI5 Tooling will ensure that all required dependencies have been built. + +If this callback is not provided, UI5 Tooling will make an assumption as to whether the custom task requires access to any resources of dependencies based on the defined Specification Version of the custom task extension: + +* **Specification Version 3.0 and later:** If no callback is provided, UI5 Tooling assumes that no dependencies are required. In this case, the `dependencies` parameter will be omitted. +* **Specification Versions before 3.0:** If no callback is provided, UI5 Tooling assumes that all dependencies are required. + + +*For more details, see also [RFC 0012 UI5 Tooling Extension API v3](https://github.com/SAP/ui5-tooling/blob/rfc-ui5-tooling-extension-api-v3/rfcs/0012-UI5-Tooling-Extension-API-3.md#3-tasks-requiring-dependencies)* + + +::: code-group +```js [ESM] +/** + * Callback function to define the list of required dependencies + * + * @param {object} parameters + * @param {Set} parameters.availableDependencies + * Set containing the names of all direct dependencies of + * the project currently being built. + * @param {function} parameters.getDependencies + * Identical to TaskUtil#getDependencies + * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). + * Creates a list of names of all direct dependencies + * of a given project. + * @param {function} parameters.getProject + * Identical to TaskUtil#getProject + * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). + * Retrieves a Project-instance for a given project name. + * @param {object} parameters.options + * Identical to the options given to the standard task function. + * @returns {Promise} + * Promise resolving with a Set containing all dependencies + * that should be made available to the task. + * UI5 Tooling will ensure that those dependencies have been + * built before executing the task. + */ +export async function determineRequiredDependencie({availableDependencies, getDependencies, getProject, options}) { + // "availableDependencies" could look like this: Set(3) { "sap.ui.core", "sap.m", "my.lib" } + // Reduce list of required dependencies: Do not require any UI5 framework projects + availableDependencies.forEach((depName) => { + if (getProject(depName).isFrameworkProject()) { + availableDependencies.delete(depName) + } + }); + // => Only resources of project "my.lib" will be available to the task + return availableDependencies; +} +``` + +```js [CommonJS] +/** + * Callback function to define the list of required dependencies + * + * @param {object} parameters + * @param {Set} parameters.availableDependencies + * Set containing the names of all direct dependencies of + * the project currently being built. + * @param {function} parameters.getDependencies + * Identical to TaskUtil#getDependencies + * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). + * Creates a list of names of all direct dependencies + * of a given project. + * @param {function} parameters.getProject + * Identical to TaskUtil#getProject + * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). + * Retrieves a Project-instance for a given project name. + * @param {object} parameters.options + * Identical to the options given to the standard task function. + * @returns {Promise} + * Promise resolving with a Set containing all dependencies + * that should be made available to the task. + * UI5 Tooling will ensure that those dependencies have been + * built before executing the task. + */ +module.exports.determineRequiredDependencies = async functio({availableDependencies, getDependencies, getProject, options}) { + // "availableDependencies" could look like this: Set(3) { "sap.ui.core", "sap.m", "my.lib" } + // Reduce list of required dependencies: Do not require any UI5 framework projects + availableDependencies.forEach((depName) => { + if (getProject(depName).isFrameworkProject()) { + availableDependencies.delete(depName) + } + }); + // => Only resources of project "my.lib" will be available to the task + return availableDependencies; +} +``` +::: + +### Examples + +The following code snippets show examples for custom task implementations. + +### Example: lib/tasks/renderMarkdownFiles.js + +This example is making use of the `resourceFactory` [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) +API to create new resources based on the output of a third-party module for rendering Markdown files. The created resources are added to the build +result by writing them into the provided `workspace`. + +::: code-group +```js [ESM] +import path from "node:path"; +import renderMarkdown from "./renderMarkdown.js"; +/* +* Render all .md (Markdown) files in the project to HTML +*/ +export default async function({dependencies, log, options, taskUtil,workspace}) { + const {createResource} = taskUtil.resourceFactory; + const textResources = await workspace.byGlob("**/*.md"); + await Promise.all(textResources.map(async (resource) => { + const markdownResourcePath = resource.getPath(); + log.info(`Rendering markdown file ${markdownResourcePath}...`); + const htmlString = await renderMarkdown(await resource.getString(), options.configuration); + // Note: @ui5/fs virtual paths are always (on *all* platforms) POSIX. Therefore using path.posix here + const newResourceName = path.posix.basename(markdownResourcePath, ".md") + ".html"; + const newResourcePath = path.posix.join(path.posix.dirname(markdownResourcePath), newResourceName); + const markdownResource = createResource({ + path: newResourcePath, + string: htmlString + }); + await workspace.write(markdownResource); + })); +}; +``` + +```js [CommonJS] +const path = require("node:path"); +const renderMarkdown = require("./renderMarkdown.js"); +/* +* Render all .md (Markdown) files in the project to HTML +*/ +module.exports = async function({dependencies, log, options, taskUtil,workspace}) { + const {createResource} = taskUtil.resourceFactory; + const textResources = await workspace.byGlob("**/*.md"); + await Promise.all(textResources.map(async (resource) => { + const markdownResourcePath = resource.getPath(); + log.info(`Rendering markdown file ${markdownResourcePath}...`); + const htmlString = await renderMarkdown(await resource.getString(), options.configuration); + // Note: @ui5/fs virtual paths are always (on *all* platforms) POSIX. Therefore using path.posix here + const newResourceName = path.posix.basename(markdownResourcePath, ".md") + ".html"; + const newResourcePath = path.posix.join(path.posix.dirname(markdownResourcePath), newResourceName); + const markdownResource = createResource({ + path: newResourcePath, + string: htmlString + }); + await workspace.write(markdownResource); + })); +}; +``` +::: + +::: warning +Depending on your project setup, UI5 Tooling tends to open many files simultaneously during a build. To prevent errors like `EMFILE: too many open files`, we urge custom task implementations to use the [graceful-fs](https://github.com/isaacs/node-graceful-fs#readme) module as a drop-in replacement for the native `fs` module in case it is used. + +Tasks should ideally use the reader/writer APIs provided by UI5 Tooling for working with project resources. +::: +### Example: lib/tasks/compileLicenseSummary.js + +This example is making use of multiple [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) +APIs to retrieve additional information about the project currently being built (`taskUtil.getProject()`) and its direct dependencies +(`taskUtil.getDependencies()`). Project configuration files like `package.json` can be accessed directly using `project.getRootReader()`. + + +::: code-group +```js [ESM]" +import path from "node:path"; +/* +* Compile a list of all licenses of the project's dependencies +* and write it to "dependency-license-summary.json" +*/ +export default async function({dependencies, log, options, taskUtil,workspace}) { + const {createResource} = taskUtil.resourceFactory; + const licenses = new Map(); + const projectsVisited = new Set(); + async function processProject(project) { + return Promise.all(taskUtil.getDependencies().map(async (projectName) => { + if (projectsVisited.has(projectName)) { + return; + } + projectsVisited.add(projectName); + const project = taskUtil.getProject(projectName); + const pkgResource = await project.getRootReader().byPath("/package.json"); + if (pkgResource) { + const pkg = JSON.parse(await pkgResource.getString()) + // Add project to list of licenses + if (licenses.has(pkg.license)) { + licenses.get(pkg.license).push(project.getName()); + } else { + // License not yet in map. Define it + licenses.set(pkg.license, [project.getName()]); + } + } else { + log.info(`Could not find package.json file in project ${project.getName()}`); + } + return processProject(project); + })); + } + // Start processing dependencies of the root project + await processProject(taskUtil.getProject()); + const summaryResource = createResource({ + path: "/dependency-license-summary.json", + string: JSON.stringify(Object.fromEntries(licenses), null, "\t") + }); + await workspace.write(summaryResource); +}; +``` + + + +```js [CommonJS] +const path = require("node:path"); +/* +* Compile a list of all licenses of the project's dependencies +* and write it to "dependency-license-summary.json" +*/ +module.exports = async function({dependencies, log, options, taskUtil,workspace}) { + const {createResource} = taskUtil.resourceFactory; + const licenses = new Map(); + const projectsVisited = new Set(); + async function processProject(project) { + return Promise.all(taskUtil.getDependencies().map(async (projectName) => { + if (projectsVisited.has(projectName)) { + return; + } + projectsVisited.add(projectName); + const project = taskUtil.getProject(projectName); + const pkgResource = await project.getRootReader().byPath("/package.json"); + if (pkgResource) { + const pkg = JSON.parse(await pkgResource.getString()) + // Add project to list of licenses + if (licenses.has(pkg.license)) { + licenses.get(pkg.license).push(project.getName()); + } else { + // License not yet in map. Define it + licenses.set(pkg.license, [project.getName()]); + } + } else { + log.info(`Could not find package.json file in project ${project.getName()}`); + } + return processProject(project); + })); + } + // Start processing dependencies of the root project + await processProject(taskUtil.getProject()); + const summaryResource = createResource({ + path: "/dependency-license-summary.json", + string: JSON.stringify(Object.fromEntries(licenses), null, "\t") + }); + await workspace.write(summaryResource); +}; +``` + +::: +## Helper Class `TaskUtil` + +Custom tasks defining [Specification Version](../Configuration.md#specification-versions) 2.2 or higher have access to an interface of a [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) instance. + +In this case, a `taskUtil` object is provided as a part of the custom task's [parameters](#task-implementation). Depending on the specification version of the custom task, a set of helper functions is available to the implementation. The lowest required specification version for every function is listed in the [TaskUtil API reference](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). diff --git a/docs/pages/extensibility/ProjectShims.md b/docs/extensibility/ProjectShims.md similarity index 100% rename from docs/pages/extensibility/ProjectShims.md rename to docs/extensibility/ProjectShims.md diff --git a/docs/index.md b/docs/index.md index 9a1e258740..38bcf21889 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,133 +1,30 @@ -![UI5 logo](images/UI5_logo_wide.png) - -# UI5 Tooling - -An open and modular toolchain to develop state-of-the-art applications based on the [UI5](https://ui5.sap.com) framework. - -!!! tip "New Release" - **UI5 Tooling V4 is here 🎉** - - Read the announcement blog post: **[SAP Community: UI5 Tooling 4.0](https://community.sap.com/t5/technology-blogs-by-sap/ui5-tooling-4-0/ba-p/13769578)** - - And checkout the **[Migrate to v4](./updates/migrate-v4.md)** documentation. - -[**Get Started**](./pages/GettingStarted.md){: .md-button .md-button--primary .sap-icon-initiative } - -## Main Features - -### 💻 UI5 CLI - -*Also see the [UI5 CLI Documentation](./pages/CLI.md)* - -```sh -# Global -npm install --global @ui5/cli - -# In your project -npm install --save-dev @ui5/cli -``` - -#### ⚙️ Project Setup - -Configure your project for use with UI5 Tooling. -*Also see the [Configuration Documentation](./pages/Configuration.md)* - -``` -❯ ui5 init -Wrote ui5.yaml: - -specVersion: "4.0" -metadata: - name: my-app -type: application -``` - -#### 🚚 Dependency Management - -UI5 framework dependencies are managed by the tooling. All other dependencies are managed by your favorite node package manager. - -``` -❯ ui5 use SAPUI5@1.117.0 -Updated configuration written to ui5.yaml -This project is now using SAPUI5 version 1.117.0 - -❯ ui5 add sap.ui.core sap.m themelib_sap_fiori_3 -Updated configuration written to ui5.yaml -Added framework libraries sap.ui.core sap.m themelib_sap_fiori_3 as dependencies -``` - -#### 🏄 Development Server - -Start a local development server to work on your project. -*Also see the [Server Documentation](./pages/Server.md)* - -``` -❯ ui5 serve -Server started -URL: http://localhost:8080 -``` - -#### 🛠 Build for Production - -Build an optimized version of your project. -*Also see the [Builder Documentation](./pages/Builder.md)* - -``` bash -❯ ui5 build -info graph:helpers:ui5Framework Using OpenUI5 version: 1.117.0 -info ProjectBuilder Preparing build for project my-app -info ProjectBuilder Target directory: ./dist -info ProjectBuilder Cleaning target directory... -info Project 1 of 1: ❯ Building application project my-app... -info my-app › Running task escapeNonAsciiCharacters... -info my-app › Running task replaceCopyright... -info my-app › Running task replaceVersion... -info my-app › Running task minify... -info my-app › Running task generateFlexChangesBundle... -info my-app › Running task generateComponentPreload... -info ProjectBuilder Build succeeded in 296 ms -info ProjectBuilder Executing cleanup tasks... -``` - -### 🧪 Node.js API - -Most UI5 Tooling modules provide JavaScript APIs for direct consumption in other Node.js projects. -This allows you to rely on UI5 Tooling for UI5-specific build functionality and project handling, while creating your own tools to perfectly match the needs of your project. - -All available APIs are documented in the [UI5 Tooling API Reference](https://sap.github.io/ui5-tooling/v4/api/index.html). - -=== "ESM" - - ```js linenums="1" - import {graphFromPackageDependencies} from "@ui5/project/graph"; - - async function buildApp(projectPath, destinationPath) { - const graph = await graphFromPackageDependencies({ - cwd: projectPath - }); - await graph.build({ - destPath: destinationPath, - selfContained: true, - excludedTasks: ["transformBootstrapHtml"], - includedDependencies: ["*"] - }); - } - ``` - -=== "CommonJS" - - ```js linenums="1" - async function buildApp(projectPath, destinationPath) { - const {graphFromPackageDependencies} = - await import("@ui5/project/graph"); - const graph = await graphFromPackageDependencies({ - cwd: projectPath - }); - await graph.build({ - destPath: destinationPath, - selfContained: true, - excludedTasks: ["transformBootstrapHtml"], - includedDependencies: ["*"] - }); - } - ``` +--- +layout: home + +hero: + name: UI5 + text: Tooling + tagline: An open and modular toolchain to develop state-of-the-art applications based on the UI5 framework. + image: + light: "/icons/ui5/B.svg" + dark: "/icons/ui5/O.svg" + actions: + - theme: brand + text: Documentation + link: /HomePage + + +features: + - icon: 0 + title: Getting Started + details: Effortlessly create beautiful documentation sites with just markdown. + link: /GettingStarted + - icon: 0 + title: Using CLI + details: Use Vue syntax and UI5 Web Components directly in markdown. + link: /CLI + - icon: 0 + title: Config + details: An API enabling a utility-first driven design system. + link: /Configuration +--- diff --git a/docs/pages/ESSupport.md b/docs/pages/ESSupport.md deleted file mode 100644 index 9c17f847a0..0000000000 --- a/docs/pages/ESSupport.md +++ /dev/null @@ -1,580 +0,0 @@ - -# ECMAScript Support - -UI5 Tooling offers general support for `ES2023` ECMAScript features. While a `ui5 build` is executed, UI5 Tooling analyses a project's code. Depending on the project type, you have to consider some restrictions regarding the usage of certain ECMAScript syntax. - -| UI5 Tooling Version | Supported ECMAScript Version | Note | -|-------------------- |----------------------------- | ---- | -| v3.11+ | ECMAScript 2023 | | -| v3.0+ | ECMAScript 2022 | | -| v2.0+ | ECMAScript 2009/ES5 | Note that code up to ECMAScript 2020 can be parsed, however required code analysis might not work correctly for specific language features | - -The following section describes all restrictions grouped by the kind of ECMAScript language feature. To get more insights into the code analysing executed by UI5 Tooling check out [Code Analysis](./CodeAnalysis.md). - -## Language Features with Restrictions - -The following sections describe the restrictions grouped by the ECMAScript language feature. - -### JavaScript modules - -In general, UI5 Tooling only analyzes **JavaScript** files of type `script`. [JavaScript Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) are not analyzed. - -UI5 Tooling and the UI5 Runtime does not support the usage of `export` and `import` of JavaScript Modules. Therefore, `sap.ui.define` has to be used. - -=== "Supported" - - ```javascript - sap.ui.define([ - "ModuleA", - "ModuleB" - ], function(ModuleA, ModuleB) { - return ModuleA.extend("ModuleC", {}); - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="1 2 3" - import ModuleA from "ModuleA"; - import ModuleB from "ModuleB"; - export default class ModuleC extends ModuleA {}; - ``` - -### Template Literal - -[Template Literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) without an expressions can be used in all places where string literals can be used. However, since UI5 Tooling will attempt a static code analysis for certain calls to UI5 API, Template Literals with one or more expressions (e.g. `Hello ${planets[2]}`) can't be used in the scenarios described below. - -#### Template Literal in `sap.ui.define` or `sap.ui.require` - -Template Literals with one or more expressions inside a `sap.ui.define` or `sap.ui.require` call are not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - `ModuleA`, - `ModuleB` - ], function(ModuleA, ModuleB) { - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="4" - const i = `B`; - sap.ui.define([ - `ModuleA`, - `Module${i}` - ], function(ModuleA, ModuleB) { - }); - ``` - -The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. - -#### Template Literal in Smart Template Declaration - -When declaring a **Smart Template** using a **Template Literal** with one or more expressions in the name of the **Smart Template** is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - `sap/suite/ui/generic/template/lib/TemplateAssembler` - ], function(TemplateAssembler) { - return TemplateAssembler.getTemplateComponent(getMethods, - `sap.suite.ui.generic.templates.Page.Component`, { - metadata: { - properties: { - templateName: { - type: `string`, - defaultValue: `sap.suite.ui.generic.templates.Page.view.Page` - } - }, - manifest: `json` - } - } - ); - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="6" - sap.ui.define([ - `sap/suite/ui/generic/template/lib/TemplateAssembler` - ], function(TemplateAssembler) { - const name = `Component`; - return TemplateAssembler.getTemplateComponent(getMethods, - `sap.suite.ui.generic.templates.Page.${name}`, { - metadata: { - properties: { - templateName: { - type: `string`, - defaultValue: `sap.suite.ui.generic.templates.Page.view.Page` - } - }, - manifest: `json` - } - } - ); - }); - ``` - -#### Template Literal in XMLComposite Declaration - -The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. - -Declaring an **XMLComposite** control using a **Template Literal** with one or more expressions in the name, is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - `sap/ui/core/XMLComposite` - ], function(XMLComposite) { - return XMLComposite.extend(`composites.MyComposite`, {} - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="5" - sap.ui.define([ - `sap/ui/core/XMLComposite` - ], function(XMLComposite) { - const name = `MyComposite`; - return XMLComposite.extend(`composites.${name}`, {}); - }); - ``` - -#### Template Literal in sap/ui/core/Core#initLibrary Call - -A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use a **Template Literal** with one or more expressions for the library name. - -=== "Supported" - - ```javascript - sap.ui.getCore().initLibrary({ - name: `my.lib` - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const libraryName = `lib`; - sap.ui.getCore().initLibrary({ - name: `my.${libraryName}` - }); - ``` - -#### Reserved Variable Names in a Template Literal - -While UI5 Tooling performs a build placeholders are replaced with a values offered by the build. For example `${version}` is replaced with the actual version defined in the package.json of the project. Therefore it is required to not use any **Template Literal** where any expression contains variable with following names: - -- `version` -- `project.version` -- `buildtime` -- `copyright` - -=== "Supported" - - ```javascript - const myVersion = `1.2`; - const transformedVersion `v${myVersion}` - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const version = `1.2`; - const transformedVersion `v${version}` - ``` - -UI5 Tooling searches for the exact match of `${version}`, so with adding whitespaces before and after the variable name `${ version }` UI5 Tooling won't replace this occurence. This can be enforced by the dedicated ESLint config [template-curly-spacing](https://eslint.org/docs/latest/rules/template-curly-spacing) with option `always`. - -### Spread Element - -A [Spread Element](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) can be used in all places, except the following. - -#### Spread Element in `sap.ui.define` or `sap.ui.require` - -A **Spread Element** as a parameter in a `sap.ui.define` or `sap.ui.require` call is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "ModuleA", - "ModuleB" - ], function(ModuleA, ModuleB) { - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const dependencies = ["ModuleA", "ModuleB"]; - sap.ui.define([ - ...dependencies - ], function(ModuleA, ModuleB) { - }); - ``` - -The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. - -#### Spread Element in Smart Template Declaration - -When declaring a **Smart Template**, the usage of a **Spread Element** in the configuration is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "sap/suite/ui/generic/template/lib/TemplateAssembler" - ], function(TemplateAssembler) { - return TemplateAssembler.getTemplateComponent(getMethods, - "sap.suite.ui.generic.templates.Page.Component", { - metadata: { - properties: { - templateName: { - type: "string", - defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" - } - }, - manifest: "json" - } - } - ); - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="6" - sap.ui.define([ - "sap/suite/ui/generic/template/lib/TemplateAssembler" - ], function(TemplateAssembler) { - const myTemplate = { - templateName: { - type: "string", - defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" - } - }; - return TemplateAssembler.getTemplateComponent(getMethods, - "sap.suite.ui.generic.templates.Page.Component", { - metadata: { - properties: { - ...myTemplate - } - manifest: "json" - } - } - ); - }); - ``` - -#### Spread Element in XMLComposite Declaration - -The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. - -When declaring an **XMLComposite**, the usage of a **Spread Element** in the configuration is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - return XMLComposite.extend("composites.MyComposite", { - fragment: "composites.custom.MyComposite" - } - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="5" - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - const myXMLComposite = { - fragment: "composites.custom.MyComposite" - }; - return XMLComposite.extend(`composites.MyComposite`, { - ...myXMLComposite - }); - }); - ``` - -#### Spread Element in sap/ui/core/Core#initLibrary Call - -A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use a **Spread Element**. - -=== "Supported" - - ```javascript - sap.ui.getCore().initLibrary({ - name: "my.lib" - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="5" - const mylib = { - name: "my.lib" - }; - sap.ui.getCore().initLibrary({ - ...mylib - }); - ``` - -### Object Expression - -An **Object Expression** can be used in all places except in following places. - -#### Object Expression in `sap.ui.define` or `sap.ui.require` - -An **Object Expression** as a parameter in a `sap.ui.define` or `sap.ui.require` call is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "Bar" - ], function(Bar){ - }); - - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const dependency = "Bar"; - sap.ui.define([ - dependency - ], function(Bar){ - }); - ``` - -The same rule applies also for the usage of deprecated or no longer recommended APIs `jQuery.sap.declare`, `jQuery.sap.declare`, `define`, `require`, `require.predefine`, `sap.ui.predefine`, `sap.ui.requireSync` and `sap.ui.require.preload`. - -#### Object Expression in Smart Template Declaration - -When declaring a **Smart Template**, the usage of an **Object Expression** in the configuration is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "sap/suite/ui/generic/template/lib/TemplateAssembler" - ], function(TemplateAssembler) { - return TemplateAssembler.getTemplateComponent(getMethods, - "sap.suite.ui.generic.templates.Page.Component", { - metadata: { - properties: { - templateName: { - type: "string", - defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" - } - }, - manifest: "json" - } - } - ); - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="9" - sap.ui.define([ - "sap/suite/ui/generic/template/lib/TemplateAssembler" - ], function(TemplateAssembler) { - const key = "templateName" - return TemplateAssembler.getTemplateComponent(getMethods, - `sap.suite.ui.generic.templates.Page.${name}`, { - metadata: { - properties: { - [key]: { - type: "string", - defaultValue: "sap.suite.ui.generic.templates.Page.view.Page" - } - } - manifest: "json" - } - } - ); - }); - ``` - -#### Object Expression in XMLComposite Declaration - -The **XMLComposite** control is deprecated since version UI5 1.88. Nevertheless UI5 Tooling will attempt to analyze the declaration of any such controls in a project. - -When declaring an **XMLComposite**, the usage of an **Object Expression** in the configuration is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - return XMLComposite.extend("composites.MyComposite", { - fragment: "composites.custom.MyComposite" - } - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="6" - sap.ui.define([ - "sap/ui/core/XMLComposite" - ], function(XMLComposite) { - const key = "fragment"; - return XMLComposite.extend("composites.MyComposite", { - [key]: "composites.custom.MyComposite" - }); - }); - ``` - -#### Object Expression in sap/ui/core/Core#initLibrary Call - -A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use an **Object Expression**. - -=== "Supported" - - ```javascript - sap.ui.getCore().initLibrary({ - name: "my.lib" - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const key = "name"; - sap.ui.getCore().initLibrary({ - [key]: "my.lib" - }); - ``` - -### Computed Property - -A **Computed Property** can be used in all places except in following places. - -#### Computed Property when using `extend` - -One or more **Computed Property** as a parameter in an UI5 Module `extend` call is not supported. - -=== "Supported" - - ```javascript - sap.ui.define([ - "Bar" - ], function(Bar){ - return Bar.extend("my.Bar" {}); - }); - - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const name = "my"; - sap.ui.define([ - "Bar" - ], function(Bar){ - return Bar.extend(name + ".Bar", {}); - }); - ``` - -#### Computed Properties in sap/ui/core/Core#initLibrary Call - -A library is typically initialized via an accompanying `library.js`. Within that file, the object which is supplied to the `sap/ui/core/Core#initLibrary` method, must not use an **Computed Property**. - -=== "Supported" - - ```javascript - sap.ui.getCore().initLibrary({ - name: "my.lib" - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="3" - const name = "my"; - sap.ui.getCore().initLibrary({ - name: name + ".lib" - }); - ``` - -### Class Declaration - -If you want to generate a JSDoc build of your project and using a **Class Declaration** the class declaration should not be returned directly. Declare the class and return the class in a separate statement. If not JSDoc treats the the class declaration as a return statement and does not recognize any JSDoc if such is provided right above the class declaration. - -=== "Supported" - - ```javascript - sap.ui.define([ - "Bar" - ], function(Bar){ - /** - * JSDoc block here - */ - class Foo extends Bar { - make () {} - } - - return Foo; - }); - ``` - -=== "Not Supported" - - ```javascript hl_lines="7" - sap.ui.define([ - "Bar" - ], function(Bar){ - /** - * JSDoc block here - */ - return class Foo extends Bar { - make () {} - } - }); - ``` - -### Arrow Function Expression - -If you want to generate a JSDoc build of your project and use an **Arrow Function Expression** the JSDoc has to be written above the arrow function and not above the `sap.ui.define/sap.ui.require` command. - -=== "Supported" - - ```javascript - sap.ui.define([ - "Bar" - ], - /** - * JSDoc block here - */ - (Bar) => Bar.extends("Foo", { - - })); - ``` - -=== "Not Supported" - - ```javascript hl_lines="1 2 3" - /** - * JSDoc block here - */ - sap.ui.define([ - "Bar" - ], (Bar) => Bar.extends("Foo", { - - })); - ``` diff --git a/docs/pages/extensibility/CustomServerMiddleware.md b/docs/pages/extensibility/CustomServerMiddleware.md deleted file mode 100644 index d901457050..0000000000 --- a/docs/pages/extensibility/CustomServerMiddleware.md +++ /dev/null @@ -1,256 +0,0 @@ -# Custom UI5 Server Middleware - -The UI5 Server Extensibility enables you to enhance the functionality of the UI5 Server. You may want to handle requests differently. For example add various headers to a response or parse data of a POST request in a specific way. For this you can plug custom middleware implementations into the internal [express](https://expressjs.com/) server of the UI5 Server module. - -The UI5 community already created many custom middleware packages which you can integrate into your project. They are often prefixed by `ui5-middleware-` to make them easily searchable in the [npm registry](https://www.npmjs.com/search?q=ui5-middleware-). - -Please note that custom middleware packages from third parties can not only modify how your project is served but also execute arbitrary code on your system. In fact, this is the case for all npm packages you install. Always act with the according care and follow best practices. - -## Configuration - -In a projects `ui5.yaml` file, you can define additional server middleware modules that will be executed when the request is received by the server. This configuration exclusively affects the server started in this project. Custom middleware configurations defined in any dependencies are ignored. - -A middleware may be executed before or after any other middleware. This can either be a [standard middleware](../Server.md#standard-middleware) or another custom middleware. - -### Example: Basic configuration - -```yaml -specVersion: "4.0" -type: application -metadata: - name: my.application -server: - customMiddleware: - - name: myCustomMiddleware - mountPath: /myapp - afterMiddleware: compression - configuration: - debug: true -``` - -In the above example the middleware `compression` is already included as a standard middleware by the UI5 Server. When serving the application `my.application`, the server will call the custom middleware `myCustomMiddleware` after `compression`. - -There can be optional configuration parameters which are passed directly to the custom middleware implementation (see below). - -An optional mountPath for which the middleware function is invoked can be provided. It will be passed to the `app.use` call (see [express API reference](https://expressjs.com/en/4x/api.html#app.use)). - -### Execution order - -Note that middleware configurations are applied in the order they are defined. When referencing another custom middleware, it has to be defined *before* that reference. - -## Custom Middleware Extension - -A custom middleware extension consists of a `ui5.yaml` and a [custom middleware implementation](#custom-middleware-implementation). It can be a standalone module or part of an existing UI5 project. - -### Example: ui5.yaml - -```yaml -specVersion: "4.0" -kind: extension -type: server-middleware -metadata: - name: markdownHandler -middleware: - path: lib/middleware/markdownHandler.js -``` - -Custom middleware extensions can be **standalone modules** which are handled as dependencies. - -Alternatively you can implement a custom middleware extension as **part of your UI5 project**. -In that case, the configuration of the extension is part of your project configuration inside the `ui5.yaml` as shown below. - -The UI5 Server will detect the custom middleware configuration of the project and use the middleware on startup. - -### Example: Custom Middleware Extension defined in UI5 project - -```yaml -# Project configuration for the above example -specVersion: "4.0" -kind: project -type: application -metadata: - name: my.application -server: - customMiddleware: - - name: markdownHandler - beforeMiddleware: serveResources ---- -# Custom middleware extension as part of your project -specVersion: "4.0" -kind: extension -type: server-middleware -metadata: - name: markdownHandler -middleware: - path: lib/middleware/markdownHandler.js -``` - -## Custom Middleware Implementation - -A custom middleware implementation needs to return a function with the following signature: - -=== "ESM" - - ```js linenums="1" - /** - * Custom UI5 Server middleware API - * - * @param {object} parameters Parameters - * @param {@ui5/logger/Logger} parameters.log - * Logger instance for use in the custom middleware. - * This parameter is only provided to custom middleware - * extensions defining Specification Version 3.0 and later. - * @param {@ui5/server.middleware.MiddlewareUtil} parameters.middlewareUtil - * Specification version-dependent interface to a - * MiddlewareUtil instance. See the corresponding API reference for details: - * https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html - * @param {object} parameters.options Options - * @param {string} parameters.options.configuration - * Custom middleware configuration, as defined in the project's ui5.yaml - * @param {string} parameters.options.middlewareName - * Name of the custom middleware. - * This parameter is only provided to custom middleware extensions - * defining Specification Version 3.0 and later - * @param {object} parameters.resources Readers for accessing resources - * @param {module:@ui5/fs.AbstractReader} parameters.resources.all - * Reader to access resources of the root project and its dependencies - * @param {module:@ui5/fs.AbstractReader} parameters.resources.rootProject - * Reader to access resources of the root project - * @param {module:@ui5/fs.AbstractReader} parameters.resources.dependencies - * Reader to access resources of the project's dependencies. - * @returns {function} Middleware function to use - */ - export default function({log, middlewareUtil, options, resources}) { - return async function (req, res, next) { - // [...] - } - }; - ``` - -=== "CommonJS" - - ```js linenums="1" - /** - * Custom UI5 Server middleware API - * - * @param {object} parameters Parameters - * @param {@ui5/logger/Logger} parameters.log - * Logger instance for use in the custom middleware. - * This parameter is only provided to custom middleware - * extensions defining Specification Version 3.0 and later. - * @param {@ui5/server.middleware.MiddlewareUtil} parameters.middlewareUtil - * Specification version-dependent interface to a - * MiddlewareUtil instance. See the corresponding API reference for details: - * https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html - * @param {object} parameters.options Options - * @param {string} parameters.options.configuration - * Custom middleware configuration, as defined in the project's ui5.yaml - * @param {string} parameters.options.middlewareName - * Name of the custom middleware. - * This parameter is only provided to custom middleware extensions - * defining Specification Version 3.0 and later - * @param {object} parameters.resources Readers for accessing resources - * @param {module:@ui5/fs.AbstractReader} parameters.resources.all - * Reader to access resources of the root project and its dependencies - * @param {module:@ui5/fs.AbstractReader} parameters.resources.rootProject - * Reader to access resources of the root project - * @param {module:@ui5/fs.AbstractReader} parameters.resources.dependencies - * Reader to access resources of the project's dependencies. - * @returns {function} Middleware function to use - */ - module.exports = function({log, middlewareUtil, options, resources}) { - return async function (req, res, next) { - // [...] - } - }; - ``` - -### Example: lib/middleware/markdownHandler.(m)js - -=== "ESM" - - ```js linenums="1" - import MarkdownIt from "markdown-it"; - - export default async function({log, middlewareUtil, options, resources}) { - const md = new MarkdownIt(); - return function (req, res, next) { - if (!req.path || !req.path.endsWith(".html")) { - // Do not handle non-HTML requests - next(); - return; - } - // Try to read a corresponding markdown file - resources.rootProject.byPath(req.path.replace(".html", ".md")).then(async (resource) => { - if (!resource) { - // No file found, hand over to next middleware - next(); - return; - } - log.info(`Rendering markdown for ${resource.getPath()}`); - const markdown = await resource.getBuffer(); - // Generate HTML from markdown string - const html = md.render(markdown.toString()); - res.type('.html'); - res.end(html); - }).catch((err) => { - next(err); - }); - } - }; - ``` - Live demo of the above example: [openui5-sample-app with custom middleware](https://github.com/SAP/openui5-sample-app/tree/demo-server-middleware-extensibility-v3-esm) - -=== "CommonJS" - - ```js linenums="1" - module.exports = async function({log, middlewareUtil, options, resources}) { - const MarkdownIt = require("markdown-it"); - const md = new MarkdownIt(); - return function (req, res, next) { - if (!req.path || !req.path.endsWith(".html")) { - // Do not handle non-HTML requests - next(); - return; - } - // Try to read a corresponding markdown file - resources.rootProject.byPath(req.path.replace(".html", ".md")).then(async (resource) => { - if (!resource) { - // No file found, hand over to next middleware - next(); - return; - } - log.info(`Rendering markdown for ${resource.getPath()}`); - const markdown = await resource.getBuffer(); - // Generate HTML from markdown string - const html = md.render(markdown.toString()); - res.type('.html'); - res.end(html); - }).catch((err) => { - next(err); - }); - } - }; - ``` - Live demo of the above example: [openui5-sample-app with custom middleware](https://github.com/SAP/openui5-sample-app/tree/demo-server-middleware-extensibility-v3) - -## Helper Class `MiddlewareUtil` - -Custom middleware defining [Specification Version](../Configuration.md#specification-versions) 2.0 or higher have access to an interface of a [MiddlewareUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html) instance. - -In this case, a `middlewareUtil` object is provided as a part of the custom middleware's [parameters](#custom-middleware-implementation). Depending on the specification version of the custom middleware, a set of helper functions is available to the implementation. The lowest required specification version for every function is listed in the [MiddlewareUtil API reference](https://sap.github.io/ui5-tooling/v4/api/@ui5_server_middleware_MiddlewareUtil.html). - -## Integration with `karma-ui5` - -!!! Warning - The Karma project has been [deprecated](https://github.com/karma-runner/karma#karma-is-deprecated-and-is-not-accepting-new-features-or-general-bug-fixes) as of 2023 - -[`karma-ui5`](https://github.com/SAP/karma-ui5) is a plugin for the popular [Karma test runner](https://karma-runner.github.io/). Based on your [configuration](https://github.com/SAP/karma-ui5#url), it can fetch resources from a dedicated server or start an internal server using parts of UI5 Tooling. - -In the latter case, any custom middleware configured in the default `ui5.yaml` of the project will be used automatically. - -However, since Karma uses the [`connect`](https://github.com/senchalabs/connect) framework, as opposed to UI5 Tooling's [`express`](https://github.com/expressjs/express), custom middleware might not always work as expected. Compared to `connect`, the `express` framework provides a more versatile API to middleware. - -Therefore, if you plan to use custom middleware in an integrated scenario with `karma-ui5`, you must **restrict the middleware to using the [`connect`](https://github.com/senchalabs/connect) API only** to ensure compatibility. - -Alternatively, you can start a server with the usual `ui5 serve` command and [configure the corresponding URL](https://github.com/SAP/karma-ui5#url) for use by `karma-ui5`. diff --git a/docs/pages/extensibility/CustomTasks.md b/docs/pages/extensibility/CustomTasks.md deleted file mode 100644 index 5fd9db3f02..0000000000 --- a/docs/pages/extensibility/CustomTasks.md +++ /dev/null @@ -1,476 +0,0 @@ -# Custom UI5 Builder Tasks - -The UI5 Build Extensibility enables you to enhance the build process of any UI5 project. In addition to the [standard tasks](../Builder.md#standard-tasks), custom tasks can be created. - -The UI5 community already created many custom tasks which you can integrate into your project. They are often prefixed by `ui5-task-` to make them easily searchable in the [npm registry](https://www.npmjs.com/search?q=ui5-task-). - -Please note that custom tasks from third parties can not only modify your project but also execute arbitrary code on your system. In fact, this is the case for all npm packages you install. Always act with the according care and follow best practices. - -## Configuration - -You can configure your build process with additional build task. These custom tasks are defined in the project [configuration](../Configuration.md). - -To hook your custom tasks into the different build phases of a project, they need to reference other tasks to be executed before or after. This can be a [standard task](../Builder.md#standard-tasks) or another custom task. -Standard tasks that are disabled, even though they are not executed, can still be referenced by custom tasks, which will be performed in their designated position. - -In the below example, when building the library `my.library` the custom `babel` task will be executed before the standard task `generateComponentPreload`. -Another custom task called `render-markdown-files` is then executed immediately after the standard task `minify`. - -### Example: Basic configuration - -```yaml -# In this example configuration, two custom tasks are defined: 'babel' and 'render-markdown-files'. -specVersion: "4.0" -type: library -metadata: - name: my.library -builder: - customTasks: - - name: babel - beforeTask: generateComponentPreload - - name: render-markdown-files - afterTask: minify - configuration: - markdownStyle: - firstH1IsTitle: true -``` - -### Example: Connect multiple custom tasks - -You can also connect multiple custom tasks with each other. The order in the configuration is important in this case. You have to make sure that a task is defined *before* you reference it via `beforeTask` or `afterTask`. - -```yaml -# In this example, 'my-custom-task-2' gets executed after 'my-custom-task-1'. -specVersion: "4.0" -type: library -metadata: - name: my.library -builder: - customTasks: - - name: my-custom-task-1 - beforeTask: generateComponentPreload - - name: my-custom-task-2 - afterTask: my-custom-task-1 -``` - -## Custom Task Extension - -A custom task extension consists of a `ui5.yaml` and a [task implementation](#task-implementation). It can be a standalone module or part of an existing UI5 project. - -### Example: ui5.yaml - -```yaml -specVersion: "4.0" -kind: extension -type: task -metadata: - name: render-markdown-files -task: - path: lib/tasks/renderMarkdownFiles.js -``` - -Task extensions can be **standalone modules** which are handled as dependencies. - -Alternatively you can implement a task extension as **part of your UI5 project**. -In that case, the configuration of the extension is part of your project configuration inside the `ui5.yaml` as shown below. - -The task extension will then be automatically collected and processed during the processing of the project. - -### Example: Custom Task Extension defined in UI5 project - -```yaml -# Project configuration for the above example -specVersion: "4.0" -kind: project -type: library -metadata: - name: my.library -builder: - customTasks: - - name: render-markdown-files - afterTask: minify - configuration: - markdownStyle: - firstH1IsTitle: true ---- -# Task extension as part of your project -specVersion: "4.0" -kind: extension -type: task -metadata: - name: render-markdown-files -task: - path: lib/tasks/renderMarkdownFiles.js -``` - -## Task Implementation - -A custom task implementation needs to return a function with the following signature: - -=== "ESM" - - ```js linenums="1" - /** - * Custom task API - * - * @param {object} parameters - * - * @param {module:@ui5/fs.AbstractReader} parameters.dependencies - * Reader to access resources of the project's dependencies - * @param {@ui5/logger/Logger} parameters.log - * Logger instance for use in the custom task. - * This parameter is only available to custom task extensions - * defining Specification Version 3.0 and later. - * @param {object} parameters.options Options - * @param {string} parameters.options.projectName - * Name of the project currently being built - * @param {string} parameters.options.projectNamespace - * Namespace of the project currently being built - * @param {string} parameters.options.configuration - * Custom task configuration, as defined in the project's ui5.yaml - * @param {string} parameters.options.taskName - * Name of the custom task. - * This parameter is only provided to custom task extensions - * defining Specification Version 3.0 and later. - * @param {@ui5/builder.tasks.TaskUtil} parameters.taskUtil - * Specification Version-dependent interface to a TaskUtil instance. - * See the corresponding API reference for details: - * https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html - * @param {module:@ui5/fs.DuplexCollection} parameters.workspace - * Reader/Writer to access and modify resources of the - * project currently being built - * @returns {Promise} - * Promise resolving once the task has finished - */ - export default async function({dependencies, log, options, taskUtil, workspace}) { - // [...] - }; - ``` - -=== "CommonJS" - - ```js linenums="1" - /** - * Custom task API - * - * @param {object} parameters - * - * @param {module:@ui5/fs.AbstractReader} parameters.dependencies - * Reader to access resources of the project's dependencies - * @param {@ui5/logger/Logger} parameters.log - * Logger instance for use in the custom task. - * This parameter is only available to custom task extensions - * defining Specification Version 3.0 and later. - * @param {object} parameters.options Options - * @param {string} parameters.options.projectName - * Name of the project currently being built - * @param {string} parameters.options.projectNamespace - * Namespace of the project currently being built - * @param {string} parameters.options.configuration - * Custom task configuration, as defined in the project's ui5.yaml - * @param {string} parameters.options.taskName - * Name of the custom task. - * This parameter is only provided to custom task extensions - * defining Specification Version 3.0 and later. - * @param {@ui5/builder.tasks.TaskUtil} parameters.taskUtil - * Specification Version-dependent interface to a TaskUtil instance. - * See the corresponding API reference for details: - * https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html - * @param {module:@ui5/fs.DuplexCollection} parameters.workspace - * Reader/Writer to access and modify resources of the - * project currently being built - * @returns {Promise} - * Promise resolving once the task has finished - */ - module.exports = async function({dependencies, log, options, taskUtil, workspace}) { - // [...] - }; - ``` - -### Required Dependencies - -!!! info - This functionality has been added with UI5 CLI [`v3.0.0`](https://github.com/SAP/ui5-cli/releases/tag/v3.0.0) - -Custom tasks can export an optional callback function `determineRequiredDependencies` to control which dependency-resources are made available through the `dependencies`-reader that is provided to the task. By reducing the amount of required dependencies or by not requiring any, UI5 Tooling might be able to build a project faster. - -Before executing a task, UI5 Tooling will ensure that all required dependencies have been built. - -If this callback is not provided, UI5 Tooling will make an assumption as to whether the custom task requires access to any resources of dependencies based on the defined Specification Version of the custom task extension: - -* **Specification Version 3.0 and later:** If no callback is provided, UI5 Tooling assumes that no dependencies are required. In this case, the `dependencies` parameter will be omitted. -* **Specification Versions before 3.0:** If no callback is provided, UI5 Tooling assumes that all dependencies are required. - - -*For more details, see also [RFC 0012 UI5 Tooling Extension API v3](https://github.com/SAP/ui5-tooling/blob/rfc-ui5-tooling-extension-api-v3/rfcs/0012-UI5-Tooling-Extension-API-3.md#3-tasks-requiring-dependencies)* - -=== "ESM" - - ```js linenums="1" - /** - * Callback function to define the list of required dependencies - * - * @param {object} parameters - * @param {Set} parameters.availableDependencies - * Set containing the names of all direct dependencies of - * the project currently being built. - * @param {function} parameters.getDependencies - * Identical to TaskUtil#getDependencies - * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). - * Creates a list of names of all direct dependencies - * of a given project. - * @param {function} parameters.getProject - * Identical to TaskUtil#getProject - * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). - * Retrieves a Project-instance for a given project name. - * @param {object} parameters.options - * Identical to the options given to the standard task function. - * @returns {Promise} - * Promise resolving with a Set containing all dependencies - * that should be made available to the task. - * UI5 Tooling will ensure that those dependencies have been - * built before executing the task. - */ - export async function determineRequiredDependencies({availableDependencies, getDependencies, getProject, options}) { - // "availableDependencies" could look like this: Set(3) { "sap.ui.core", "sap.m", "my.lib" } - - // Reduce list of required dependencies: Do not require any UI5 framework projects - availableDependencies.forEach((depName) => { - if (getProject(depName).isFrameworkProject()) { - availableDependencies.delete(depName) - } - }); - // => Only resources of project "my.lib" will be available to the task - return availableDependencies; - } - ``` - -=== "CommonJS" - - ```js linenums="1" - /** - * Callback function to define the list of required dependencies - * - * @param {object} parameters - * @param {Set} parameters.availableDependencies - * Set containing the names of all direct dependencies of - * the project currently being built. - * @param {function} parameters.getDependencies - * Identical to TaskUtil#getDependencies - * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). - * Creates a list of names of all direct dependencies - * of a given project. - * @param {function} parameters.getProject - * Identical to TaskUtil#getProject - * (see https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). - * Retrieves a Project-instance for a given project name. - * @param {object} parameters.options - * Identical to the options given to the standard task function. - * @returns {Promise} - * Promise resolving with a Set containing all dependencies - * that should be made available to the task. - * UI5 Tooling will ensure that those dependencies have been - * built before executing the task. - */ - module.exports.determineRequiredDependencies = async function({availableDependencies, getDependencies, getProject, options}) { - // "availableDependencies" could look like this: Set(3) { "sap.ui.core", "sap.m", "my.lib" } - - // Reduce list of required dependencies: Do not require any UI5 framework projects - availableDependencies.forEach((depName) => { - if (getProject(depName).isFrameworkProject()) { - availableDependencies.delete(depName) - } - }); - // => Only resources of project "my.lib" will be available to the task - return availableDependencies; - } - ``` - -### Examples - -The following code snippets show examples for custom task implementations. - -### Example: lib/tasks/renderMarkdownFiles.js - -This example is making use of the `resourceFactory` [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) -API to create new resources based on the output of a third-party module for rendering Markdown files. The created resources are added to the build -result by writing them into the provided `workspace`. - -=== "ESM" - - ```js linenums="1" - import path from "node:path"; - import renderMarkdown from "./renderMarkdown.js"; - - /* - * Render all .md (Markdown) files in the project to HTML - */ - export default async function({dependencies, log, options, taskUtil, workspace}) { - const {createResource} = taskUtil.resourceFactory; - const textResources = await workspace.byGlob("**/*.md"); - await Promise.all(textResources.map(async (resource) => { - const markdownResourcePath = resource.getPath(); - - log.info(`Rendering markdown file ${markdownResourcePath}...`); - const htmlString = await renderMarkdown(await resource.getString(), options.configuration); - - // Note: @ui5/fs virtual paths are always (on *all* platforms) POSIX. Therefore using path.posix here - const newResourceName = path.posix.basename(markdownResourcePath, ".md") + ".html"; - const newResourcePath = path.posix.join(path.posix.dirname(markdownResourcePath), newResourceName); - - const markdownResource = createResource({ - path: newResourcePath, - string: htmlString - }); - await workspace.write(markdownResource); - })); - }; - ``` - -=== "CommonJS" - - ```js linenums="1" - const path = require("node:path"); - const renderMarkdown = require("./renderMarkdown.js"); - - /* - * Render all .md (Markdown) files in the project to HTML - */ - module.exports = async function({dependencies, log, options, taskUtil, workspace}) { - const {createResource} = taskUtil.resourceFactory; - const textResources = await workspace.byGlob("**/*.md"); - await Promise.all(textResources.map(async (resource) => { - const markdownResourcePath = resource.getPath(); - - log.info(`Rendering markdown file ${markdownResourcePath}...`); - const htmlString = await renderMarkdown(await resource.getString(), options.configuration); - - // Note: @ui5/fs virtual paths are always (on *all* platforms) POSIX. Therefore using path.posix here - const newResourceName = path.posix.basename(markdownResourcePath, ".md") + ".html"; - const newResourcePath = path.posix.join(path.posix.dirname(markdownResourcePath), newResourceName); - - const markdownResource = createResource({ - path: newResourcePath, - string: htmlString - }); - await workspace.write(markdownResource); - })); - }; - ``` - -!!! warning - Depending on your project setup, UI5 Tooling tends to open many files simultaneously during a build. To prevent errors like `EMFILE: too many open files`, we urge custom task implementations to use the [graceful-fs](https://github.com/isaacs/node-graceful-fs#readme) module as a drop-in replacement for the native `fs` module in case it is used. - - Tasks should ideally use the reader/writer APIs provided by UI5 Tooling for working with project resources. - -### Example: lib/tasks/compileLicenseSummary.js - -This example is making use of multiple [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) -APIs to retrieve additional information about the project currently being built (`taskUtil.getProject()`) and its direct dependencies -(`taskUtil.getDependencies()`). Project configuration files like `package.json` can be accessed directly using `project.getRootReader()`. - -=== "ESM" - - ```js linenums="1" - import path from "node:path"; - - /* - * Compile a list of all licenses of the project's dependencies - * and write it to "dependency-license-summary.json" - */ - export default async function({dependencies, log, options, taskUtil, workspace}) { - const {createResource} = taskUtil.resourceFactory; - const licenses = new Map(); - const projectsVisited = new Set(); - - async function processProject(project) { - return Promise.all(taskUtil.getDependencies().map(async (projectName) => { - if (projectsVisited.has(projectName)) { - return; - } - projectsVisited.add(projectName); - const project = taskUtil.getProject(projectName); - const pkgResource = await project.getRootReader().byPath("/package.json"); - if (pkgResource) { - const pkg = JSON.parse(await pkgResource.getString()) - - // Add project to list of licenses - if (licenses.has(pkg.license)) { - licenses.get(pkg.license).push(project.getName()); - } else { - // License not yet in map. Define it - licenses.set(pkg.license, [project.getName()]); - } - - } else { - log.info(`Could not find package.json file in project ${project.getName()}`); - } - return processProject(project); - })); - } - // Start processing dependencies of the root project - await processProject(taskUtil.getProject()); - - const summaryResource = createResource({ - path: "/dependency-license-summary.json", - string: JSON.stringify(Object.fromEntries(licenses), null, "\t") - }); - await workspace.write(summaryResource); - }; - ``` - -=== "CommonJS" - - ```js linenums="1" - const path = require("node:path"); - - /* - * Compile a list of all licenses of the project's dependencies - * and write it to "dependency-license-summary.json" - */ - module.exports = async function({dependencies, log, options, taskUtil, workspace}) { - const {createResource} = taskUtil.resourceFactory; - const licenses = new Map(); - const projectsVisited = new Set(); - - async function processProject(project) { - return Promise.all(taskUtil.getDependencies().map(async (projectName) => { - if (projectsVisited.has(projectName)) { - return; - } - projectsVisited.add(projectName); - const project = taskUtil.getProject(projectName); - const pkgResource = await project.getRootReader().byPath("/package.json"); - if (pkgResource) { - const pkg = JSON.parse(await pkgResource.getString()) - - // Add project to list of licenses - if (licenses.has(pkg.license)) { - licenses.get(pkg.license).push(project.getName()); - } else { - // License not yet in map. Define it - licenses.set(pkg.license, [project.getName()]); - } - - } else { - log.info(`Could not find package.json file in project ${project.getName()}`); - } - return processProject(project); - })); - } - // Start processing dependencies of the root project - await processProject(taskUtil.getProject()); - - const summaryResource = createResource({ - path: "/dependency-license-summary.json", - string: JSON.stringify(Object.fromEntries(licenses), null, "\t") - }); - await workspace.write(summaryResource); - }; - ``` - -## Helper Class `TaskUtil` - -Custom tasks defining [Specification Version](../Configuration.md#specification-versions) 2.2 or higher have access to an interface of a [TaskUtil](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html) instance. - -In this case, a `taskUtil` object is provided as a part of the custom task's [parameters](#task-implementation). Depending on the specification version of the custom task, a set of helper functions is available to the implementation. The lowest required specification version for every function is listed in the [TaskUtil API reference](https://sap.github.io/ui5-tooling/v4/api/@ui5_project_build_helpers_TaskUtil.html). diff --git a/docs/public/TripPinClassDiagram.jpg b/docs/public/TripPinClassDiagram.jpg new file mode 100644 index 0000000000..44dfb5669c Binary files /dev/null and b/docs/public/TripPinClassDiagram.jpg differ diff --git a/docs/public/UI5-VitePress-fire-and-water.jpg b/docs/public/UI5-VitePress-fire-and-water.jpg new file mode 100644 index 0000000000..87a85d9784 Binary files /dev/null and b/docs/public/UI5-VitePress-fire-and-water.jpg differ diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico new file mode 100644 index 0000000000..8e7584c1ab Binary files /dev/null and b/docs/public/favicon.ico differ diff --git a/docs/public/icons/logo/Autoprefixer.svg b/docs/public/icons/logo/Autoprefixer.svg new file mode 100644 index 0000000000..7e19cb3c17 --- /dev/null +++ b/docs/public/icons/logo/Autoprefixer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/PlantUML.svg b/docs/public/icons/logo/PlantUML.svg new file mode 100644 index 0000000000..96535d4553 --- /dev/null +++ b/docs/public/icons/logo/PlantUML.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/public/icons/logo/PostCSS.svg b/docs/public/icons/logo/PostCSS.svg new file mode 100644 index 0000000000..baf9b1e760 --- /dev/null +++ b/docs/public/icons/logo/PostCSS.svg @@ -0,0 +1 @@ +postcss-logo-symbol diff --git a/docs/public/icons/logo/Rollup.svg b/docs/public/icons/logo/Rollup.svg new file mode 100644 index 0000000000..20bb5dfe63 --- /dev/null +++ b/docs/public/icons/logo/Rollup.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/public/icons/logo/TailwindCSS.svg b/docs/public/icons/logo/TailwindCSS.svg new file mode 100644 index 0000000000..e0e971530c --- /dev/null +++ b/docs/public/icons/logo/TailwindCSS.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/public/icons/logo/TypeScript-wm.svg b/docs/public/icons/logo/TypeScript-wm.svg new file mode 100644 index 0000000000..3c9fa5d366 --- /dev/null +++ b/docs/public/icons/logo/TypeScript-wm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/TypeScript.svg b/docs/public/icons/logo/TypeScript.svg new file mode 100644 index 0000000000..a46d53d49f --- /dev/null +++ b/docs/public/icons/logo/TypeScript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/UI5.svg b/docs/public/icons/logo/UI5.svg new file mode 100644 index 0000000000..c54ff84762 --- /dev/null +++ b/docs/public/icons/logo/UI5.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/public/icons/logo/VitePress.svg b/docs/public/icons/logo/VitePress.svg new file mode 100644 index 0000000000..ed6438ade1 --- /dev/null +++ b/docs/public/icons/logo/VitePress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/Vitejs.svg b/docs/public/icons/logo/Vitejs.svg new file mode 100644 index 0000000000..de4aeddc12 --- /dev/null +++ b/docs/public/icons/logo/Vitejs.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/public/icons/logo/Vuejs.svg b/docs/public/icons/logo/Vuejs.svg new file mode 100644 index 0000000000..a6c05382d6 --- /dev/null +++ b/docs/public/icons/logo/Vuejs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/Web-Components.svg b/docs/public/icons/logo/Web-Components.svg new file mode 100644 index 0000000000..a1e3ce54c3 --- /dev/null +++ b/docs/public/icons/logo/Web-Components.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/cssnano-wm-vertical.svg b/docs/public/icons/logo/cssnano-wm-vertical.svg new file mode 100644 index 0000000000..8faebaf4da --- /dev/null +++ b/docs/public/icons/logo/cssnano-wm-vertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/cssnano-wm.svg b/docs/public/icons/logo/cssnano-wm.svg new file mode 100644 index 0000000000..e0a266aa49 --- /dev/null +++ b/docs/public/icons/logo/cssnano-wm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/cssnano.svg b/docs/public/icons/logo/cssnano.svg new file mode 100644 index 0000000000..58bfe27f2d --- /dev/null +++ b/docs/public/icons/logo/cssnano.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/docs/public/icons/logo/markdown.svg b/docs/public/icons/logo/markdown.svg new file mode 100644 index 0000000000..efaefee739 --- /dev/null +++ b/docs/public/icons/logo/markdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/logo/powering-sap-btp.svg b/docs/public/icons/logo/powering-sap-btp.svg new file mode 100644 index 0000000000..260b75880f --- /dev/null +++ b/docs/public/icons/logo/powering-sap-btp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/B.svg b/docs/public/icons/ui5/B.svg new file mode 100644 index 0000000000..b5c1033309 --- /dev/null +++ b/docs/public/icons/ui5/B.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/B_OpenUI5_H.svg b/docs/public/icons/ui5/B_OpenUI5_H.svg new file mode 100644 index 0000000000..0b66b01e83 --- /dev/null +++ b/docs/public/icons/ui5/B_OpenUI5_H.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/B_OpenUI5_V.svg b/docs/public/icons/ui5/B_OpenUI5_V.svg new file mode 100644 index 0000000000..00be266e41 --- /dev/null +++ b/docs/public/icons/ui5/B_OpenUI5_V.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/B_UI5_H.svg b/docs/public/icons/ui5/B_UI5_H.svg new file mode 100644 index 0000000000..690ee70443 --- /dev/null +++ b/docs/public/icons/ui5/B_UI5_H.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/B_UI5_V.svg b/docs/public/icons/ui5/B_UI5_V.svg new file mode 100644 index 0000000000..fd78b9bc78 --- /dev/null +++ b/docs/public/icons/ui5/B_UI5_V.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/O.svg b/docs/public/icons/ui5/O.svg new file mode 100644 index 0000000000..122eacd4ab --- /dev/null +++ b/docs/public/icons/ui5/O.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/O_OpenUI5_H.svg b/docs/public/icons/ui5/O_OpenUI5_H.svg new file mode 100644 index 0000000000..633e548432 --- /dev/null +++ b/docs/public/icons/ui5/O_OpenUI5_H.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/O_OpenUI5_V.svg b/docs/public/icons/ui5/O_OpenUI5_V.svg new file mode 100644 index 0000000000..d272c1a348 --- /dev/null +++ b/docs/public/icons/ui5/O_OpenUI5_V.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/O_UI5_H.svg b/docs/public/icons/ui5/O_UI5_H.svg new file mode 100644 index 0000000000..b0659ccbbb --- /dev/null +++ b/docs/public/icons/ui5/O_UI5_H.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/O_UI5_V.svg b/docs/public/icons/ui5/O_UI5_V.svg new file mode 100644 index 0000000000..79304ca259 --- /dev/null +++ b/docs/public/icons/ui5/O_UI5_V.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/icons/ui5/UI5.svg b/docs/public/icons/ui5/UI5.svg new file mode 100644 index 0000000000..c54ff84762 --- /dev/null +++ b/docs/public/icons/ui5/UI5.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/public/learn-more.svg b/docs/public/learn-more.svg new file mode 100644 index 0000000000..22a412cd6e --- /dev/null +++ b/docs/public/learn-more.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/public/tailwind-css-vsc-color-completion.png b/docs/public/tailwind-css-vsc-color-completion.png new file mode 100644 index 0000000000..889123407f Binary files /dev/null and b/docs/public/tailwind-css-vsc-color-completion.png differ diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css deleted file mode 100644 index cbc02d2937..0000000000 --- a/docs/stylesheets/extra.css +++ /dev/null @@ -1,199 +0,0 @@ -@font-face { - font-family: "SAP-icons"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/SAP-icons.woff2") format("woff2"), local("SAP-icons"); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 400; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Regular.woff2") format("woff2"), local("72"); -} -@font-face { - font-family: "72full"; - font-style: normal; - font-weight: 400; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Regular-full.woff2") format("woff2"); -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 700; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold.woff2") format("woff2"), local("72-Bold"); -} -@font-face { - font-family: "72full"; - font-style: normal; - font-weight: 700; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 300; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light.woff2") format("woff2"), local("72-Light"); -} -@font-face { - font-family: "72full"; - font-style: normal; - font-weight: 300; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-Bold"; - font-style: normal; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold.woff2") format("woff2"), local("72-Bold"); -} -@font-face { - font-family: "72-Boldfull"; - font-style: normal; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-Light"; - font-style: normal; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light.woff2") format("woff2"), local("72-Light"); -} -@font-face { - font-family: "72-Lightfull"; - font-style: normal; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Mono"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Regular.woff2") format("woff2"), local("72Mono"); -} -@font-face { - font-family: "72Monofull"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Regular-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Mono-Bold"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Bold.woff2") format("woff2"), local("72Mono-Bold"); -} -@font-face { - font-family: "72Mono-Boldfull"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Black"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2") format("woff2"); -} -@font-face { - font-family: "72Blackfull"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-SemiboldDuplex"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-SemiboldDuplex.woff2") format("woff2"); -} -@font-face { - font-family: "72-SemiboldDuplexfull"; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-SemiboldDuplex-full.woff2") format("woff2"); -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 400; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Regular-full.woff2") format("woff2"); -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 700; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72"; - font-style: normal; - font-weight: 300; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-Bold"; - font-style: normal; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-Light"; - font-style: normal; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Mono"; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Regular-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Mono-Bold"; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Bold-full.woff2") format("woff2"); -} -@font-face { - font-family: "72Black"; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black-full.woff2") format("woff2"); -} -@font-face { - font-family: "72-SemiboldDuplex"; - unicode-range: U+0102-0103, U+010F, U+013D, U+013E, U+0165, U+01A0-01A1, - U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, - U+1EE4-1EF1, U+1EF4-1EF7; - src: url("https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-SemiboldDuplex-full.woff2") format("woff2"); -} - -html, body, h1, h2, h3, h4, h5, h6, p { - font-family: "72-Regular", "72", "72full", Arial, Helvetica, sans-serif; -} - -.sap-icon-initiative::before { - font-family: SAP-icons; - content: "\e161"; - margin-right: 0.5em; -} - -.sap-icon-accept::before { - font-family: SAP-icons; - content: "\e05b"; -} - -.sap-icon-ui5-after::after { - font-family: SAP-icons; - content: "\e21b"; - margin-left: 0.5em; - color: var(--md-primary-fg-color); -} - -.ui5-footer-item { - flex-grow: 0; - color: var(--md-footer-fg-color--lighter); - font-size: .64rem; - margin: auto 0.6rem; - padding: 0.4rem 0; -} - -.md-copyright { - flex-grow: 1; -} diff --git a/docs/updates/migrate-v3.md b/docs/updates/migrate-v3.md index 301810d2ae..aa2744333f 100644 --- a/docs/updates/migrate-v3.md +++ b/docs/updates/migrate-v3.md @@ -1,10 +1,10 @@ # Migrate to v3 -!!! warning "Superseded" - **UI5 Tooling 3.0 has been superseded by version 4.0. See [Migrate to v4](./migrate-v4.md).** - - Find the announcement blog post for version 3.0 here: **[SAP Community: UI5 Tooling 3.0](https://blogs.sap.com/2023/02/10/ui5-tooling-3.0/)** +::: warning +**UI5 Tooling 3.0 has been superseded by version 4.0. See [Migrate to v4](./migrate-v4.md).** +Find the announcement blog post for version 3.0 here: **[SAP Community: UI5 Tooling 3.0](https://blogs.sap.com/2023/02/10/ui5-tooling-3.0/)** +::: ## Node.js and npm Version Support **This release requires Node.js versions v16.18.0, v18.12.0 or higher as well as npm v8 or higher.** @@ -19,9 +19,9 @@ This means your old projects might still work. Unless they have non-standard con ## Changes for Projects -!!! info - ✅ Projects defining **Specification Version 2.x** are expected to be **fully compatible with UI5 Tooling v3** +::: info ✅ Projects defining **Specification Version 2.x** are expected to be **fully compatible with UI5 Tooling v3** +::: For projects defining the latest **Specification Versions 3.0 and higher**, some changes apply: * **Breaking Change:** The `metadata.name` property is now restricted to contain only certain characters and no uppercase letters. See [Configuration: `name`](../pages/Configuration.md#name) for details @@ -30,8 +30,9 @@ See also [Configuration: Specification Version 3.0](../pages/Configuration.md#sp ## Changes for Extensions -!!! info - ✅ Custom Tasks and Custom Middleware defining **Specification Version 2.x** are expected to be **fully compatible with UI5 Tooling v3** +::: info ✅ Custom Tasks and Custom Middleware defining **Specification Version 2.x** are expected to be **fully compatible with UI5 Tooling v3** + +::: For extensions defining the latest **Specification Versions 3.0 and higher**, some changes and improvements apply: @@ -44,28 +45,28 @@ For extensions defining the latest **Specification Versions 3.0 and higher**, so ## Changes to Dependency Configuration -!!! info - ✅ The **`ui5.dependencies` package.json configuration** becomes obsolete and is ignored in UI5 Tooling v3. +::: info ✅ The **`ui5.dependencies` package.json configuration** becomes obsolete and is ignored in UI5 Tooling v3. - Configuration like the following is not needed anymore: - ```diff title="package.json" - { - [...] - - "ui5": { - - "dependencies": [ - - "my-package" - - ] - - } - [...] - } - ``` +Configuration like the following is not needed anymore: - `dependencies`, `devDependencies` and `optionalDependencies` are now [automatically analyzed](https://github.com/SAP/ui5-project/blob/ff04ae4aeeb7f7d889dffd0c0e3e8774dd708c79/lib/graph/providers/NodePackageDependencies.js#L104). - If a dependency can be configured as a UI5 project or UI5 Tooling extension, it is added to the graph and its `dependencies` are analyzed. +```diff title="package.json" {3-7} +{ + [...] +- "ui5": { +- "dependencies": [ +- "my-package" +- ] +- } + [...] +} +``` - Note that `devDependencies` and `optionalDependencies` are ignored for all but the current root project. For projects that are intended to be consumed in other projects (for example libraries), this means that any required custom tasks must be added to `dependencies`. +`dependencies`, `devDependencies` and `optionalDependencies` are now [automatically analyzed](https://github.com/SAP/ui5-project/blob/ff04ae4aeeb7f7d889dffd0c0e3e8774dd708c79/lib/graph/providers/NodePackageDependencies.js#L104). +If a dependency can be configured as a UI5 project or UI5 Tooling extension, it is added to the graph and its `dependencies` are analyzed. +Note that `devDependencies` and `optionalDependencies` are ignored for all but the current root project. For projects that are intended to be consumed in other projects (for example libraries), this means that any required custom tasks must be added to `dependencies`. +::: ## Changes to Module API The `normalizer` and `projectTree` modules have been removed. The `builder` API has been moved from @ui5/builder to @ui5/project. @@ -96,11 +97,24 @@ await builder.build({ ``` **New: @ui5/project v3** +::: code-group + +```js [ESM] +import {graphFromPackageDependencies} from "@ui5/project/graph"; + +let graph = await graphFromPackageDependencies({cwd: "."}); + +await graph.build({ + destPath: "./dist", + includedDependencies: ["*"], // Parameter "buildDependencies" has been removed +}); +``` -=== "ESM" - ```js - import {graphFromPackageDependencies} from "@ui5/project/graph"; +```js [CommonJS] +// Since CommonJS does not suport top-level await, the code must be wrapped in an asynchronous function +async function buildProject() { + const {graphFromPackageDependencies} = await import("@ui5/project/graph"); let graph = await graphFromPackageDependencies({cwd: "."}); @@ -108,23 +122,9 @@ await builder.build({ destPath: "./dist", includedDependencies: ["*"], // Parameter "buildDependencies" has been removed }); - ``` - -=== "CommonJS" - - ```js - // Since CommonJS does not suport top-level await, the code must be wrapped in an asynchronous function - async function buildProject() { - const {graphFromPackageDependencies} = await import("@ui5/project/graph"); - - let graph = await graphFromPackageDependencies({cwd: "."}); - - await graph.build({ - destPath: "./dist", - includedDependencies: ["*"], // Parameter "buildDependencies" has been removed - }); - } - ``` +} +``` +::: ## Changes to @ui5/cli @@ -145,10 +145,11 @@ Especially for projects of type `library`, where standard tasks like [`buildThem In the future, a caching mechanism should help and improve build times with this new behavior. -!!! info - The CLI flags `-a` and `--all` are still present and now an alias for `--include-all-dependencies`. This flag (along with `--include-dependency*` and `--exclude-dependency*`) mainly controls the **build output**. Use it to define whether dependency resources should be part of the build result. +::: tip Info +The CLI flags `-a` and `--all` are still present and now an alias for `--include-all-dependencies`. This flag (along with `--include-dependency*` and `--exclude-dependency*`) mainly controls the **build output**. Use it to define whether dependency resources should be part of the build result. - Please also refer to the [`ui5 build` documentation](../pages/CLI.md#ui5-build). +Please also refer to the [`ui5 build` documentation](../pages/CLI.md#ui5-build). +::: ## Removal of Standard Tasks and Processors @@ -169,7 +170,7 @@ The following processors have been removed: | UI5 Tooling v2 | UI5 Tooling v3 | Note | | --------------------------- | --------------------------- | ------------------------- | -| createDebugFiles
uglify | minify | The minify task is executed earlier, before the bundling process takes place. Any existing `beforeTask` or `afterTask` configuration of custom tasks might need to be adapted to cater for this change.
To adapt, you can use the `generateResourcesJson` task for subscription before or after the last standard task. By default, `generateResourcesJson` is disabled, but you can still subscribe to it, thereby ensuring that your custom tasks execute in the correct order. | +| createDebugFiles uglify | minify | The minify task is executed earlier, before the bundling process takes place. Any existing `beforeTask` or `afterTask` configuration of custom tasks might need to be adapted to cater for this change.
To adapt, you can use the `generateResourcesJson` task for subscription before or after the last standard task. By default, `generateResourcesJson` is disabled, but you can still subscribe to it, thereby ensuring that your custom tasks execute in the correct order. | | generateVersionInfo | generateVersionInfo | The task is no longer executed by default for application projects. It can be re-enabled by using the `--include-task` parameter. | | generateManifestBundle | *None* | This task was only needed for the HTML5 repository in Cloud Foundry. Meanwhile, the HTML5 repository implemented its own mechanism, so the task is no longer needed | @@ -181,39 +182,39 @@ The following processors have been removed: | replaceCopyright | *enabled* | *enabled* | *enabled* | | replaceVersion | *enabled* | *enabled* | *enabled* | | replaceBuildtime | | *enabled* | | -| generateJsdoc | | *disabled* ^1^ | | -| executeJsdocSdkTransformation | | *disabled* ^1^ | | +| generateJsdoc | | *disabled¹* | | +| executeJsdocSdkTransformation | | *disabled¹* | | | **ADDED:** minify | *enabled* | *enabled* | | | generateFlexChangesBundle | *enabled* | *enabled* | | | **REMOVED:** ~~generateManifestBundle~~ | *~~disabled~~* | *~~disabled~~* | | | generateLibraryManifest | | *enabled* | | -| generateComponentPreload | *enabled* | *disabled* ^2^ | | +| generateComponentPreload | *enabled* | *disabled²* | | | generateLibraryPreload | | *enabled* | | -| generateStandaloneAppBundle | *disabled* ^3^ | | | -| transformBootstrapHtml | *disabled* ^3^ | | | -| generateBundle | *disabled* ^4^ | *disabled* ^4^ | | +| generateStandaloneAppBundle | *disabled³* | | | +| transformBootstrapHtml | *disabled³* | | | +| generateBundle | *disabled⁴* | *disabled⁴* | | | buildThemes | | *enabled* | *enabled* | -| generateThemeDesignerResources | | *disabled* ^5^ | *disabled* ^5^ | +| generateThemeDesignerResources | | *disabled⁵* | *disabled⁵* | | **REMOVED:** ~~createDebugFiles~~ | *~~enabled~~* | *~~enabled~~* | | | **REMOVED:** ~~uglify~~ | *~~enabled~~* | *~~enabled~~* | | | generateVersionInfo | **disabled** | | | | generateCachebusterInfo | *disabled* | | | -| generateApiIndex | *disabled* ^1^ | | | +| generateApiIndex | *disabled¹* | | | | generateResourcesJson | *disabled* | *disabled* | *disabled* | *Disabled tasks can be activated by certain build modes, the project configuration, or by using the `--include-task` [CLI parameter](../pages/CLI.md#ui5-build). See footnotes where given* --- -^1^ Enabled in `jsdoc` build, which disables most of the other tasks -^2^ Enabled for projects defining a [component preload configuration](../pages/Configuration.md#component-preload-generation) -^3^ Enabled in `self-contained` build, which disables `generateComponentPreload` and `generateLibraryPreload` -^4^ Enabled for projects defining a [bundle configuration](../pages/Configuration.md#custom-bundling) -^5^ Can be enabled for framework projects via the `includeTask` option. For other projects, this task is skipped +¹ Enabled in `jsdoc` build, which disables most of the other tasks +² Enabled for projects defining a [component preload configuration](../pages/Configuration.md#component-preload-generation) +³ Enabled in `self-contained` build, which disables `generateComponentPreload` and `generateLibraryPreload` +⁴ Enabled for projects defining a [bundle configuration](../pages/Configuration.md#custom-bundling) +⁵ Can be enabled for framework projects via the `includeTask` option. For other projects, this task is skipped ## Removal of Standard Middleware -The following middleware has been removed from the [standard middlewares list](../../pages/Server/#standard-middleware): +The following middleware has been removed from the [standard middlewares list](.../../pages/Server/#standard-middleware): * connectUi5Proxy diff --git a/docs/updates/migrate-v4.md b/docs/updates/migrate-v4.md index 7f8ef2d522..b96dc44311 100644 --- a/docs/updates/migrate-v4.md +++ b/docs/updates/migrate-v4.md @@ -1,13 +1,14 @@ # Migrate to v4 -!!! tip "In Development" - **UI5 Tooling 4.0 has been released on July 24, 2024 🎉** +::: tip In Development - Install the latest version in your projects via: `npm i --save-dev @ui5/cli@latest` - And update your global install via `npm i --global @ui5/cli@latest` +**UI5 Tooling 4.0 has been released on July 24, 2024 🎉** - And find the announcement blog post here: **[SAP Community: UI5 Tooling 4.0](https://community.sap.com/t5/technology-blogs-by-sap/ui5-tooling-4-0/ba-p/13769578)** +Install the latest version in your projects via: `npm i --save-dev @ui5/cli@latest` +And update your global install via `npm i --global @ui5/cli@latest` +And find the announcement blog post here: **[SAP Community: UI5 Tooling 4.0](https://community.sap.com/t5/technology-blogs-by-sap/ui5-tooling-4-0/ba-p/13769578)** +::: ## UI5 2.x Compatibility *Also see the blog post [SAP Community: Introducing OpenUI5 2.x](https://community.sap.com/t5/open-source-blogs/introducing-openui5-2-x/ba-p/13580633)* @@ -30,10 +31,13 @@ Old projects might therefore still work, unless they have a non-standard configu ## Changes for Projects -!!! success "No changes for Specification Versions 2.x and 3.x" - Projects defining **Specification Version 2.x or 3.x** are expected to be **fully compatible with UI5 Tooling v4** - The following does not apply to them. +::: tip No changes for Specification Versions 2.x and 3.x + +Projects defining **Specification Version 2.x or 3.x** are expected to be **fully compatible with UI5 Tooling v4** + +The following does not apply to them. +::: For projects defining the latest **Specification Version 4.0 or higher**, the following changes apply: @@ -78,45 +82,43 @@ Non-public `DuplexCollection#byGlobSource` API has been removed. - **New Option**: Added a new `async` option for `builder.bundles.bundleDefinition.section`. -!!! example - ```yaml - builder: - bundles: - - bundleDefinition: - name: "app.js" - sections: - - mode: require - filters: - - some/app/Component.js - resolve: true - sort: true - async: true - ``` +> [!IMPORTANT] Example +>```yaml +>builder: +> bundles: +> - bundleDefinition: +> name: "app.js" +> sections: +> - mode: require +> filters: +> - some/app/Component.js +> resolve: true +> sort: true +> async: true +>``` ### Changes to @ui5/project -- **Default Workspace Name**: The default `workspaceName` is now `"default"` for API usage. +**Default Workspace Name**: The default `workspaceName` is now `"default"` for API usage. + +```js +import {graphFromPackageDependencies} from "@ui5/project/graph"; -!!! example - ```js - import {graphFromPackageDependencies} from "@ui5/project/graph"; - - graphFromPackageDependencies({ - /* workspaceName: "default" */ - }); - ``` +graphFromPackageDependencies({ + /* workspaceName: "default" */ +}); +``` -- **Directory Naming**: The `ui5HomeDir` has been renamed to `ui5DataDir` in APIs. +**Directory Naming**: The `ui5HomeDir` has been renamed to `ui5DataDir` in APIs. -!!! example - ```js - import Resolver from "@ui5/project/ui5Framework/Openui5Resolver"; +```js +import Resolver from "@ui5/project/ui5Framework/Openui5Resolver"; - await Resolver.resolveVersion("1.120.15", { - ui5DataDir: "~/.ui5", - cwd: process.cwd() - }); - ``` +await Resolver.resolveVersion("1.120.15", { + ui5DataDir: "~/.ui5", + cwd: process.cwd() +}); +``` - **Dependencies**: The `@ui5/builder` is now an optional dependency to the `@ui5/project` diff --git a/eslint.config.js b/eslint.config.js index d6565f5547..aa9b635e51 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -4,7 +4,7 @@ export default [ { // Add project-specific ignore patterns for ESLint here // to add to common config - ignores: ["**/site/"] + ignores: ["**/site/", ".vitepress", "src", "tailwind.config.js", "docs", "postcss.config.js"] }, ...eslintCommonConfig, // Load common ESLint config { diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index e7976635a8..0000000000 --- a/mkdocs.yml +++ /dev/null @@ -1,92 +0,0 @@ -site_name: UI5 Tooling -site_url: 'https://sap.github.io/ui5-tooling/' # required for working 404 page -repo_name: 'SAP/ui5-tooling' -repo_url: 'https://github.com/SAP/ui5-tooling' -edit_uri: ./edit/main/docs # default points to "master" branch -docs_dir: 'docs' # default -site_dir: 'site' # default -copyright: '© Copyright 2024, SAP SE and UI5 Tooling Contributors' -nav: - - Home: index.md - - Getting Started: pages/GettingStarted.md - - UI5 CLI: pages/CLI.md - - Configuration: pages/Configuration.md - - Development: - - Overview: pages/Overview.md - - OpenUI5: pages/OpenUI5.md - - SAPUI5: pages/SAPUI5.md - - Workspace: pages/Workspace.md - - Extensibility: - - Custom Tasks: pages/extensibility/CustomTasks.md - - Custom Server Middleware: pages/extensibility/CustomServerMiddleware.md - - Project Shims: pages/extensibility/ProjectShims.md - - Modules: - - Server: pages/Server.md - - Builder: pages/Builder.md - - Project: pages/Project.md - - File System: pages/FileSystem.md - - Upgrade Guides: - - Migrate to v4: updates/migrate-v4.md - - Migrate to v3: updates/migrate-v3.md - - Migrate to v2: updates/migrate-v2.md - - Migrate to v1: updates/migrate-v1.md - - FAQ: pages/FAQ.md - - Miscellaneous: - - Troubleshooting: pages/Troubleshooting.md - - Benchmarking: pages/Benchmarking.md - - ECMAScript Support: pages/ESSupport.md - - Code Analysis: pages/CodeAnalysis.md - - API Reference: 'api/index.html' # only available in final build, not serve - -theme: - name: 'material' - custom_dir: 'overrides' - palette: - primary: 'blue' - accent: 'blue' - logo: 'images/logo.svg' - favicon: 'images/favicon.png' - font: false - features: - - navigation.expand - -extra_css: - - 'stylesheets/extra.css' - -extra: - version: - provider: mike - -plugins: - - search - - minify: - minify_html: true - - mike: - canonical_version: null - version_selector: true - css_dir: stylesheets - javascript_dir: js - -markdown_extensions: - - admonition - - attr_list - - codehilite: - guess_lang: false - - toc: - permalink: true - # PyMdown Extensions Documentation: https://facelessuser.github.io/pymdown-extensions/extensions/betterem/ - - pymdownx.betterem: - smart_enable: all - - pymdownx.details - - pymdownx.inlinehilite - - pymdownx.magiclink - - pymdownx.mark - - pymdownx.keys - - pymdownx.smartsymbols - - pymdownx.tabbed: - alternate_style: true - - pymdownx.superfences - - pymdownx.tasklist: - custom_checkbox: true - - pymdownx.tilde - - pymdownx.caret diff --git a/overrides/partials/footer.html b/overrides/partials/footer.html deleted file mode 100644 index 0be1a43854..0000000000 --- a/overrides/partials/footer.html +++ /dev/null @@ -1,58 +0,0 @@ -{#- - This file was initialy copied from https://github.com/squidfunk/mkdocs-material/blob/-/material/partials/footer.html - and adjusted to offer a customized footer according to the SAP Web Presence Policy. - See also the corresponding stylesheet content in /docs/stylesheets/extra.css. --#} - diff --git a/package-lock.json b/package-lock.json index e8feff947e..197bc5797a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,13 @@ "devDependencies": { "@apidevtools/json-schema-ref-parser": "^11.7.0", "@eslint/js": "^9.8.0", + "@odata2ts/http-client-fetch": "^0.6.2", + "@odata2ts/odata2ts": "^0.35.0", + "@types/markdown-it-plantuml": "^1.4.5", + "@types/node": "^20.14.9", + "@ui5/webcomponents": "^1.24.5", + "autoprefixer": "^10.4.19", + "cssnano": "^7.0.3", "depcheck": "^1.4.7", "docdash": "^2.0.2", "eslint": "^9.9.1", @@ -29,8 +36,15 @@ "handlebars": "^4.7.8", "jsdoc": "^4.0.3", "local-web-server": "^5.4.0", + "markdown-it-implicit-figures": "^0.12.0", + "markdown-it-link-attributes": "^4.0.1", + "markdown-it-plantuml": "^1.4.1", "open-cli": "^8.0.0", - "traverse": "^0.6.9" + "postcss": "^8.4.38", + "tailwindcss": "^3.4.4", + "traverse": "^0.6.9", + "vitepress": "^1.2.3", + "vue": "^3.4.30" }, "engines": { "node": "^20.11.0 || >=22.0.0", @@ -55,6 +69,343 @@ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==" }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.1.1.tgz", + "integrity": "sha512-jkQNQbGY+XQB3Eln7wqqdUZKBzG8lETcsaUk5gcMc6iIwyN/qW0v0fhpKPH+Kli+BImLxo0CWk12CvVvx2exWA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.1.1.tgz", + "integrity": "sha512-SFpb3FI/VouGou/vpuS7qeCA5Y/KpV42P6CEA/1MZQtl/xJkl6PVjikb+Q9YadeHi2jtDV/aQ6PyiVDnX4PQcw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.1.1", + "@algolia/requester-browser-xhr": "5.1.1", + "@algolia/requester-node-http": "5.1.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.1.1.tgz", + "integrity": "sha512-NXmN1ujJCj5GlJQaMK6DbdiXdcf6nhRef/X40lu9TYi71q9xTo/5RPMI0K2iOp6g07S26BrXFOz6RSV3Ny4LLw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.1.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.1.1.tgz", + "integrity": "sha512-xwrgnNTIzgxDEx6zuCKSKTPzQLA8fL/WZiVB6fRpIu5agLMjoAi0cWA5YSDbo+2FFxqVgLqKY/Jz6mKmWtY15Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.1.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@apidevtools/json-schema-ref-parser": { "version": "11.7.0", "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", @@ -252,6 +603,81 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", + "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docsearch/js": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.1.tgz", + "integrity": "sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/react": "3.6.1", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/react": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", + "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.1", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.48.0", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.48.0.tgz", @@ -266,90 +692,481 @@ "node": ">=16" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@eslint/config-array/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { "node": "*" @@ -634,6 +1451,13 @@ "node": ">= 14.0.0" } }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -896,36 +1720,522 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" + "node_modules/@odata2ts/converter-api": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@odata2ts/converter-api/-/converter-api-0.1.2.tgz", + "integrity": "sha512-3KaXbzKiu6rOh8/kP7hv26e4PN2JQ/YZuobzkOvl4swfkxZjKOLcM221tNH/TVGm40SZFkLRV7pf1HenvvET2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@odata2ts/odata-core": "^0.1.0" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "node_modules/@odata2ts/converter-api/node_modules/@odata2ts/odata-core": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-core/-/odata-core-0.1.0.tgz", + "integrity": "sha512-kiLHbZu6ewBjfxpATL0NQXhFG+5XZlCBmmiEQMAF5elSMMrQIrf09wd7vurx0/4MnrLYkcPh/v6/CR5XaQE9Pw==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" + "license": "MIT" + }, + "node_modules/@odata2ts/converter-runtime": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@odata2ts/converter-runtime/-/converter-runtime-0.2.2.tgz", + "integrity": "sha512-u0EeG4pfjrUhOKD6SWro3jfv0dAOqHFkEKYDr2qkkwYreOhf1ND9oAh2zTuuyNyCPY0ONpHVttyBbtAQd4eiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@odata2ts/converter-api": "^0.1.2" } }, - "node_modules/@sigstore/bundle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", - "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "node_modules/@odata2ts/http-client-api": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@odata2ts/http-client-api/-/http-client-api-0.5.1.tgz", + "integrity": "sha512-k5rzpeOuWbPvYj40Qy1ZmP2G3EFD6kqk7np5VpSmXL9ZTZtS3Vzi6+aJM1uO2W8/4RDpzlBzyrLc2hjLgSPw4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@odata2ts/http-client-base": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@odata2ts/http-client-base/-/http-client-base-0.4.2.tgz", + "integrity": "sha512-LqW9p6aa5PnAgNBYGG1VEf/sFTy+JC3fioI2/BP/1dW5ZpV1PBPOa35RyALcBtb+TgdfFfbuzJVUmI/FJsj8mQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "@odata2ts/http-client-api": "^0.5.1" + } + }, + "node_modules/@odata2ts/http-client-fetch": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@odata2ts/http-client-fetch/-/http-client-fetch-0.6.2.tgz", + "integrity": "sha512-8tzVfAHpJp7yVFrmRrYcUoCcoqZSwzbVyagasaZken7Axsxx7P6Qbe/pCv93zgAcLtu0pSsNQevXBOOuBVGuNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@odata2ts/http-client-base": "^0.4.2" + } + }, + "node_modules/@odata2ts/odata-core": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-core/-/odata-core-0.5.0.tgz", + "integrity": "sha512-oAtKUsa9lUt/G8qHvf9fb9bMHc+TCc2tgKfXtDjLd4v3HGY3dEhP85ODT70tI1iugRNnSvm83hlbndwr3BlnFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@odata2ts/odata-query-builder": { + "version": "0.16.10", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-query-builder/-/odata-query-builder-0.16.10.tgz", + "integrity": "sha512-yxGFyOHU5xU0vtTy3fXZEkM1lCTnaMTOeQpGRNxcczguFQxoIY1ZrmO6G5jNYXO64D8tMWEZeKawWiXSOtkhPw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@odata2ts/odata-query-objects": "^0.23.1" + } + }, + "node_modules/@odata2ts/odata-query-builder/node_modules/@odata2ts/odata-query-objects": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-query-objects/-/odata-query-objects-0.23.1.tgz", + "integrity": "sha512-uPs15IjpbjthneBXi01tE4W1BWBVvvOKXiKQPMTF4QEVeTZx5UB17QTsb7KZUZZgN2D4zA4yd0Zj3zRVyVAQfQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@odata2ts/converter-api": "^0.1.2", + "@odata2ts/http-client-api": "^0.5.1", + "@odata2ts/odata-core": "^0.5.0" + } + }, + "node_modules/@odata2ts/odata-query-objects": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-query-objects/-/odata-query-objects-0.21.0.tgz", + "integrity": "sha512-Spcrf5n6QAC7A+RX5laRaCIqi57rCrXv2Qdx6Zt6WctapjOu5J/M+UOD/kvr5TdJ7FN+gSmdl9ZdnF+R8r/tzA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@odata2ts/converter-api": "^0.1.2", + "@odata2ts/http-client-api": "^0.1.0", + "@odata2ts/odata-core": "^0.5.0" + } + }, + "node_modules/@odata2ts/odata-query-objects/node_modules/@odata2ts/http-client-api": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@odata2ts/http-client-api/-/http-client-api-0.1.0.tgz", + "integrity": "sha512-mbIRS535/AldQ19fxj3rTXUGn3b8VltVKN4poIcwVBmqKUI/cY0aP9q/zDrGp8RBHNOEm/S+0qSQI8GEiAFS1A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@odata2ts/odata-service": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-service/-/odata-service-0.19.3.tgz", + "integrity": "sha512-hq9I68r5UPKqt9ZOnBjsVJrtsvbJt1l0YcZGOQx9IxJ3TssFru9iTZNfnIupCC4eSRWzKsf1/P8DBfEfxWhn+g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@odata2ts/http-client-api": "^0.5.1", + "@odata2ts/odata-query-builder": "^0.16.10", + "@odata2ts/odata-query-objects": "^0.23.1" + } + }, + "node_modules/@odata2ts/odata-service/node_modules/@odata2ts/odata-query-objects": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@odata2ts/odata-query-objects/-/odata-query-objects-0.23.1.tgz", + "integrity": "sha512-uPs15IjpbjthneBXi01tE4W1BWBVvvOKXiKQPMTF4QEVeTZx5UB17QTsb7KZUZZgN2D4zA4yd0Zj3zRVyVAQfQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@odata2ts/converter-api": "^0.1.2", + "@odata2ts/http-client-api": "^0.5.1", + "@odata2ts/odata-core": "^0.5.0" + } + }, + "node_modules/@odata2ts/odata2ts": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@odata2ts/odata2ts/-/odata2ts-0.35.0.tgz", + "integrity": "sha512-JZgWazoBVW1DyDwMiaTs7UFKVcZV7aaCkCCuzk0KgQBivBMwo/+15LOEDJTSuw40XJ74rwFWD7uECc5dTvKXWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@odata2ts/converter-api": "^0.1.2", + "@odata2ts/converter-runtime": "^0.2.2", + "@odata2ts/http-client-api": "^0.5.1", + "@odata2ts/odata-core": "^0.5.0", + "@prettier/plugin-xml": "^2.2.0", + "axios": "^1.4.0", + "camel-case": "^4.1.2", + "commander": "^10.0.1", + "constant-case": "^3.0.4", + "cosmiconfig": "^8.2.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "deepmerge": "^4.3.1", + "fs-extra": "^11.1.1", + "pascal-case": "^3.1.2", + "prettier": "^2.8.8", + "snake-case": "^3.0.4", + "ts-morph": "^18.0.0", + "ts-node": "^10.9.1", + "tsconfig-loader": "^1.1.0", + "upper-case-first": "^2.0.2", + "xml2js": "^0.6.0" + }, + "bin": { + "odata2ts": "lib/run-cli.js" + }, + "peerDependencies": { + "@odata2ts/odata-query-objects": "^0.21.0", + "@odata2ts/odata-service": "^0.19.0" + } + }, + "node_modules/@odata2ts/odata2ts/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@odata2ts/odata2ts/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@odata2ts/odata2ts/node_modules/cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^1.19.1" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@prettier/plugin-xml": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-2.2.0.tgz", + "integrity": "sha512-UWRmygBsyj4bVXvDiqSccwT1kmsorcwQwaIy30yVh8T+Gspx4OlC0shX1y+ZuwXZvgnafmpRYKks0bAu9urJew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xml-tools/parser": "^1.0.11", + "prettier": ">=2.4.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz", + "integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz", + "integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz", + "integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz", + "integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz", + "integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz", + "integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz", + "integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz", + "integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz", + "integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz", + "integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz", + "integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz", + "integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz", + "integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz", + "integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz", + "integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz", + "integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sap-theming/theming-base-content": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@sap-theming/theming-base-content/-/theming-base-content-11.12.0.tgz", + "integrity": "sha512-kPHlziH8e6W8VjzljOiNjgBz81GuvC8WUAi7K6F5k+ZaRc1DUkDU12x9k6B0l4u9nPtprdZTse55r3PFGuELdQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@shikijs/core": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.14.1.tgz", + "integrity": "sha512-KyHIIpKNaT20FtFPFjCQB5WVSTpLR/n+jQXhWHWVUMm9MaOaG9BGOG0MSyt7yA4+Lm+4c9rTc03tt3nYzeYSfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/transformers": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.14.1.tgz", + "integrity": "sha512-JJqL8QBVCJh3L61jqqEXgFq1cTycwjcGj7aSmqOEsbxnETM9hRlaB74QuXvY/fVJNjbNt8nvWo0VwAXKvMSLRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shiki": "1.14.1" + } + }, + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@sigstore/core": { @@ -1011,6 +2321,89 @@ "node": ">= 10" } }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.19.0.tgz", + "integrity": "sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.12", + "minimatch": "^7.4.3", + "mkdirp": "^2.1.6", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, "node_modules/@tufjs/canonical-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", @@ -1045,6 +2438,33 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/jquery": { + "version": "3.5.30", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.30.tgz", + "integrity": "sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sizzle": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1065,6 +2485,16 @@ "@types/mdurl": "^2" } }, + "node_modules/@types/markdown-it-plantuml": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@types/markdown-it-plantuml/-/markdown-it-plantuml-1.4.5.tgz", + "integrity": "sha512-QTEJOz9UJSJhLNTYXbjg3p/MsEY3TIgzVH3r1zf/tfXOclf/E2lmP8ZXOkv7RdD4agnMROO4h/3IFWCElEvR8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/markdown-it": "*" + } + }, "node_modules/@types/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", @@ -1076,18 +2506,74 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, + "node_modules/@types/node": { + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==" }, + "node_modules/@types/openui5": { + "version": "1.127.0", + "resolved": "https://registry.npmjs.org/@types/openui5/-/openui5-1.127.0.tgz", + "integrity": "sha512-MIauyuHgaNnN7PDMZ71vS9XqpVlo0tXL6EaMhdmNjQTMblm6IJxlmOz0UX1BkdJwGKIA2rVE+2WGz6xn7ndJaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jquery": "~3.5.13", + "@types/qunit": "^2.5.4" + } + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true }, - "node_modules/@ui5/builder": { + "node_modules/@types/qunit": { + "version": "2.19.10", + "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.19.10.tgz", + "integrity": "sha512-gVB+rxvxmbyPFWa6yjjKgcumWal3hyqoTXI0Oil161uWfo1OCzWZ/rnEumsx+6uVgrwPrCrhpQbLkzfildkSbg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ui5/builder": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@ui5/builder/-/builder-4.0.2.tgz", "integrity": "sha512-dO60oanh7rDojmGvvz9cynOOL7GErsBhrokEtYuQcnHM+OnY+xwvVQEoQ8MylrCPtc5GOTB6wQR+zu4i6JlsOQ==", @@ -6767,6 +8253,98 @@ "npm": ">= 8" } }, + "node_modules/@ui5/webcomponents": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents/-/webcomponents-1.24.8.tgz", + "integrity": "sha512-lqFIcTt9wPGPluc6ok3uQ11waKceNgvL4ge8Q+l5Eg6l+WIHlg1rB+FPwY7JbONq4S0cCbMugwIgRlOhfNyVqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ui5/webcomponents-base": "1.24.8", + "@ui5/webcomponents-icons": "1.24.8", + "@ui5/webcomponents-icons-business-suite": "1.24.8", + "@ui5/webcomponents-icons-tnt": "1.24.8", + "@ui5/webcomponents-localization": "1.24.8", + "@ui5/webcomponents-theming": "1.24.8" + } + }, + "node_modules/@ui5/webcomponents-base": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-base/-/webcomponents-base-1.24.8.tgz", + "integrity": "sha512-sU5bHebMeIoWtm6Ul3mYsvK3uj5veRTQRUZHwc+4lv/rK/iJ4BpzoQPsHNIlKg2xwPdZJmFWfCt1PpPTAc6n6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.1.2", + "lit-html": "^2.0.1" + } + }, + "node_modules/@ui5/webcomponents-icons": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-icons/-/webcomponents-icons-1.24.8.tgz", + "integrity": "sha512-zozw+/S68nCx1qzFbYqE+PS7xkkxFFTZAkZ5ID5O5IHlvt6egjgQL9TKx/gOC2kJtTfO5ZcCJpEToGaTDEB2ig==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ui5/webcomponents-base": "1.24.8" + } + }, + "node_modules/@ui5/webcomponents-icons-business-suite": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-icons-business-suite/-/webcomponents-icons-business-suite-1.24.8.tgz", + "integrity": "sha512-MsmEfKNiMH2iSuyYzYAYwABJax5oBUYPytwin0vFi2181dqT7tn5ZboCHVcR6a083E22aLm1vfM58Lus96y0Tg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ui5/webcomponents-base": "1.24.8" + } + }, + "node_modules/@ui5/webcomponents-icons-tnt": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-icons-tnt/-/webcomponents-icons-tnt-1.24.8.tgz", + "integrity": "sha512-U68ASfgYREZzJSTSI9yb0uS6ODgojHURvShUXn1fe1rVJYh7ZEBqwQfI11kxiiefKyZScJrvRHOYN44i0tXUDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ui5/webcomponents-base": "1.24.8" + } + }, + "node_modules/@ui5/webcomponents-localization": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-localization/-/webcomponents-localization-1.24.8.tgz", + "integrity": "sha512-SxD93MlOvTIU/Z2BLWyIy2K9RNnNE5ZvI6getBd/3g7ofumhVZ9cha4Z+8CxLBwKYva3dNXTZUgLtndVMr/4DA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/openui5": "^1.113.0", + "@ui5/webcomponents-base": "1.24.8" + } + }, + "node_modules/@ui5/webcomponents-theming": { + "version": "1.24.8", + "resolved": "https://registry.npmjs.org/@ui5/webcomponents-theming/-/webcomponents-theming-1.24.8.tgz", + "integrity": "sha512-8f5oXIb99gyPzHQJTyYvabQBJ7AQY4ufbaf9NH1ZoVei1MYxuaBh/R7JrvXAzvn/eSHQi6fDc1xJERDJhMDF0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sap-theming/theming-base-content": "11.12.0", + "@ui5/webcomponents-base": "1.24.8" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.2.tgz", + "integrity": "sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, "node_modules/@vue/compiler-core": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz", @@ -6817,12 +8395,293 @@ "@vue/shared": "3.4.38" } }, + "node_modules/@vue/devtools-api": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.3.8.tgz", + "integrity": "sha512-NURFwmxz4WukFU54IHgyGI2KSejdgHG5JC4xTcWmTWEBIc8aelj9fBy4qsboObGHFp3JIdRxxANO9s2wZA/pVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.3.8" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.3.8.tgz", + "integrity": "sha512-HYy3MQP1nZ6GbE4vrgJ/UB+MvZnhYmEwCa/UafrEpdpwa+jNCkz1ZdUrC5I7LpkH1ShREEV2/pZlAQdBj+ncLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.3.8", + "birpc": "^0.2.17", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.3.8.tgz", + "integrity": "sha512-1NiJbn7Yp47nPDWhFZyEKpB2+5/+7JYv8IQnU0ccMrgslPR2dL7u1DIyI7mLqy4HN1ll36gQy0k8GqBYSFgZJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.38.tgz", + "integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.4.38" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.38.tgz", + "integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.4.38", + "@vue/shared": "3.4.38" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz", + "integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.4.38", + "@vue/runtime-core": "3.4.38", + "@vue/shared": "3.4.38", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.38.tgz", + "integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.4.38", + "@vue/shared": "3.4.38" + }, + "peerDependencies": { + "vue": "3.4.38" + } + }, "node_modules/@vue/shared": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz", "integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==", "dev": true }, + "node_modules/@vueuse/core": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.0.1.tgz", + "integrity": "sha512-YTrekI18WwEyP3h168Fir94G/HNC27wvXJI21Alm0sPOwvhihfkrvHIe+5PNJq+MpgWdRcsjvE/38JaoKrgZhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "11.0.1", + "@vueuse/shared": "11.0.1", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.0.1.tgz", + "integrity": "sha512-V/FQTS/aiV6RTFXOj8cXgqhtNJBvxvbHeLElOUR7N7F3Kr0btS+dkymLB54mFd0Or6uEGpgwwb41cs/q2/rdOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vueuse/core": "11.0.1", + "@vueuse/shared": "11.0.1", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.0.1.tgz", + "integrity": "sha512-dTFvuHFAjLYOiSd+t9Sk7xUiuL6jbfay/eX+g+jaipXXlwKur2VCqBCZX+jfu+2vROUGcUsdn3fJR9KkpadIOg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.0.1.tgz", + "integrity": "sha512-eAPf5CQB3HR0S76HqrhjBqFYstZfiHWZq8xF9EQmobGBkrhPfErJEhr8aMNQMqd6MkENIx2pblIEfJGlHpClug==", + "dev": true, + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@xml-tools/parser": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz", + "integrity": "sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "chevrotain": "7.1.1" + } + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -6862,6 +8721,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -6932,6 +8804,73 @@ "ajv": ">=5.0.0" } }, + "node_modules/algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, "node_modules/ansi-escape-sequences": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", @@ -6963,6 +8902,27 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/are-docs-informative": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", @@ -6972,6 +8932,13 @@ "node": ">=14" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7064,23 +9031,80 @@ "lodash": "^4.17.14" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, - "node_modules/balanced-match": { - "version": "1.0.2", + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, @@ -7102,6 +9126,29 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/birpc": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.17.tgz", + "integrity": "sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -7154,6 +9201,39 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -7262,6 +9342,17 @@ "node": ">=6" } }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -7274,6 +9365,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -7421,6 +9556,54 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz", + "integrity": "sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "regexp-to-ast": "0.5.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -7557,6 +9740,13 @@ "node": ">=8.0.0" } }, + "node_modules/code-block-writer": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", + "dev": true, + "license": "MIT" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -7570,6 +9760,26 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", @@ -7673,6 +9883,18 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -7737,6 +9959,22 @@ "node": ">= 0.8" } }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/copy-to": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", @@ -7785,6 +10023,13 @@ "node": ">=10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7844,6 +10089,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -7859,6 +10117,20 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -7870,6 +10142,141 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.5.tgz", + "integrity": "sha512-Aq0vqBLtpTT5Yxj+hLlLfNPFuRQCDIjx5JQAhhaedQKLNDvDGeVziF24PS+S1f0Z5KCxWvw0QVI3VNHNBITxVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^7.0.5", + "lilconfig": "^3.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.5.tgz", + "integrity": "sha512-Jbzja0xaKwc5JzxPQoc+fotKpYtWEu4wQLMQe29CM0FjjdRjA4omvbGHl2DTGgARKxSTpPssBsok+ixv8uTBqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.0", + "postcss-calc": "^10.0.1", + "postcss-colormin": "^7.0.2", + "postcss-convert-values": "^7.0.3", + "postcss-discard-comments": "^7.0.2", + "postcss-discard-duplicates": "^7.0.1", + "postcss-discard-empty": "^7.0.0", + "postcss-discard-overridden": "^7.0.0", + "postcss-merge-longhand": "^7.0.3", + "postcss-merge-rules": "^7.0.3", + "postcss-minify-font-values": "^7.0.0", + "postcss-minify-gradients": "^7.0.0", + "postcss-minify-params": "^7.0.2", + "postcss-minify-selectors": "^7.0.3", + "postcss-normalize-charset": "^7.0.0", + "postcss-normalize-display-values": "^7.0.0", + "postcss-normalize-positions": "^7.0.0", + "postcss-normalize-repeat-style": "^7.0.0", + "postcss-normalize-string": "^7.0.0", + "postcss-normalize-timing-functions": "^7.0.0", + "postcss-normalize-unicode": "^7.0.2", + "postcss-normalize-url": "^7.0.0", + "postcss-normalize-whitespace": "^7.0.0", + "postcss-ordered-values": "^7.0.1", + "postcss-reduce-initial": "^7.0.2", + "postcss-reduce-transforms": "^7.0.0", + "postcss-svgo": "^7.0.1", + "postcss-unique-selectors": "^7.0.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.0.tgz", + "integrity": "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, "node_modules/current-module-paths": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.2.tgz", @@ -7959,6 +10366,16 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/default-browser": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", @@ -8029,6 +10446,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -8203,6 +10630,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, "node_modules/docdash": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/docdash/-/docdash-2.0.2.tgz", @@ -8263,16 +10714,34 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/electron-to-chromium": { + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", + "dev": true, + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -8503,6 +10972,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -9297,6 +11805,37 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -9321,6 +11860,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -9329,6 +11883,20 @@ "node": ">= 0.6" } }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -9337,6 +11905,21 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fs-minipass": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", @@ -9348,6 +11931,21 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -9737,6 +12335,13 @@ "node": ">=0.10.0" } }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, "node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", @@ -10167,6 +12772,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -10497,6 +13115,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -10546,6 +13177,16 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10675,6 +13316,19 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -11096,6 +13750,19 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -11110,6 +13777,16 @@ "uc.micro": "^2.0.0" } }, + "node_modules/lit-html": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", + "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, "node_modules/load-module": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/load-module/-/load-module-5.0.0.tgz", @@ -11197,6 +13874,13 @@ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==" }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -11209,6 +13893,23 @@ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", "dev": true }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -11468,6 +14169,13 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, "node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", @@ -11490,6 +14198,13 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -11515,6 +14230,30 @@ "markdown-it": "*" } }, + "node_modules/markdown-it-implicit-figures": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/markdown-it-implicit-figures/-/markdown-it-implicit-figures-0.12.0.tgz", + "integrity": "sha512-IeD2V74f3ZBYrZ+bz/9uEGii0S61BYoD2731qsHTgYLlENUrTevlgODScScS1CK44/TV9ddlufGHCYCQueh1rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-it-link-attributes": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz", + "integrity": "sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it-plantuml": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/markdown-it-plantuml/-/markdown-it-plantuml-1.4.1.tgz", + "integrity": "sha512-13KgnZaGYTHBp4iUmGofzZSBz+Zj6cyqfR0SXUIc9wgWTto5Xhn7NjaXYxY0z7uBeTUMlc9LMQq5uP4OM5xCHg==", + "dev": true, + "license": "MIT" + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -11526,6 +14265,13 @@ "node": ">= 12" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -11757,6 +14503,13 @@ "node": ">=8" } }, + "node_modules/minisearch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz", + "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==", + "dev": true, + "license": "MIT" + }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -11780,6 +14533,13 @@ "node": ">=8" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -11865,6 +14625,18 @@ "node": "*" } }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -11903,6 +14675,17 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-gyp": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", @@ -11926,6 +14709,13 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, "node_modules/node-stream-zip": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", @@ -11965,6 +14755,26 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-bundled": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", @@ -12071,6 +14881,16 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -12350,233 +15170,861 @@ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/peek-readable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.1.4.tgz", + "integrity": "sha512-E7mY2VmKqw9jYuXrSWGHFuPCW2SLQenzXLF3amGaY6lXXg4/b3gj5HVM7h8ZjCO/nZS9ICs0Cz285+32FvNd/A==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/portscanner": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", + "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", + "dependencies": { + "async": "^2.6.0", + "is-number-like": "^1.0.3" + }, + "engines": { + "node": ">=0.4", + "npm": ">=1.0.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.0.2.tgz", + "integrity": "sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/postcss-colormin": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.2.tgz", + "integrity": "sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.3.tgz", + "integrity": "sha512-yJhocjCs2SQer0uZ9lXTMOwDowbxvhwFVrZeS6NPEij/XXthl73ggUmfwVvJM+Vaj5gtCKJV1jiUu4IhAUkX/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.2.tgz", + "integrity": "sha512-/Hje9Ls1IYcB9duELO/AyDUJI6aQVY3h5Rj1ziXgaLYCTi1iVBLnjg/TS0D6NszR/kDG6I86OwLmAYe+bvJjiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.1.tgz", + "integrity": "sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.0.tgz", + "integrity": "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.0.tgz", + "integrity": "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.3.tgz", + "integrity": "sha512-8waYomFxshdv6M9Em3QRM9MettRLDRcH2JQi2l0Z1KlYD/vhal3gbkeSES0NuACXOlZBB0V/B0AseHZaklzWOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.3.tgz", + "integrity": "sha512-2eSas2p3voPxNfdI5sQrvIkMaeUHpVc3EezgVs18hz/wRTQAC9U99tp9j3W5Jx9/L3qHkEDvizEx/LdnmumIvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.0", + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.0.tgz", + "integrity": "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.0.tgz", + "integrity": "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.2.tgz", + "integrity": "sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.3.tgz", + "integrity": "sha512-SxTgUQSgBk6wEqzQZKEv1xQYIp9UBju6no9q+npohzSdhuSICQdkqmD1UMKkZWItS3olJSJMDDEY9WOJ5oGJew==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" }, "engines": { - "node": ">=8" + "node": ">=12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "postcss": "^8.2.14" } }, - "node_modules/parse-json/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "node_modules/postcss-normalize-charset": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz", + "integrity": "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/parse5-htmlparser2-tree-adapter": { + "node_modules/postcss-normalize-display-values": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.0.tgz", + "integrity": "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==", + "dev": true, + "license": "MIT", "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" + "postcss-value-parser": "^4.2.0" }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "node_modules/postcss-normalize-positions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.0.tgz", + "integrity": "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==", + "dev": true, + "license": "MIT", "dependencies": { - "parse5": "^7.0.0" + "postcss-value-parser": "^4.2.0" }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { - "node": ">= 0.8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/postcss-normalize-repeat-style": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.0.tgz", + "integrity": "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==", "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/postcss-normalize-string": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.0.tgz", + "integrity": "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==", "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/postcss-normalize-timing-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.0.tgz", + "integrity": "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/postcss-normalize-unicode": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.2.tgz", + "integrity": "sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==", + "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/postcss-normalize-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.0.tgz", + "integrity": "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==", "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/peek-readable": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.1.4.tgz", - "integrity": "sha512-E7mY2VmKqw9jYuXrSWGHFuPCW2SLQenzXLF3amGaY6lXXg4/b3gj5HVM7h8ZjCO/nZS9ICs0Cz285+32FvNd/A==", + "node_modules/postcss-normalize-whitespace": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.0.tgz", + "integrity": "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==", "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=14.16" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/postcss-ordered-values": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.1.tgz", + "integrity": "sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=8.6" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "node_modules/postcss-reduce-initial": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.2.tgz", + "integrity": "sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^5.0.0" + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "node_modules/postcss-reduce-transforms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.0.tgz", + "integrity": "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==", "dev": true, + "license": "MIT", "dependencies": { - "semver-compare": "^1.0.0" + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/portscanner": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", - "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", "dependencies": { - "async": "^2.6.0", - "is-number-like": "^1.0.3" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=0.4", - "npm": ">=1.0.0" + "node": ">=4" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "node_modules/postcss-svgo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.1.tgz", + "integrity": "sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==", "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.3.2" + }, "engines": { - "node": ">= 0.4" + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "node_modules/postcss-unique-selectors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.2.tgz", + "integrity": "sha512-CjSam+7Vf8cflJQsHrMS0P2hmy9u0+n/P001kb5eAszLmhjMqrt/i5AqQuNFihhViwDvEAezqTmXqaYXL2ugMw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "postcss-selector-parser": "^6.1.1" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" } }, "node_modules/prelude-ls": { @@ -12588,6 +16036,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-data": { "version": "0.40.0", "resolved": "https://registry.npmjs.org/pretty-data/-/pretty-data-0.40.0.tgz", @@ -12646,6 +16110,13 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -12737,6 +16208,16 @@ "node": ">= 0.8" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/read-package-json-fast": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", @@ -12849,6 +16330,13 @@ "node": ">=6" } }, + "node_modules/regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==", + "dev": true, + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -13048,6 +16536,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rimraf": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", @@ -13122,10 +16617,46 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz", + "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.21.0", + "@rollup/rollup-android-arm64": "4.21.0", + "@rollup/rollup-darwin-arm64": "4.21.0", + "@rollup/rollup-darwin-x64": "4.21.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.0", + "@rollup/rollup-linux-arm-musleabihf": "4.21.0", + "@rollup/rollup-linux-arm64-gnu": "4.21.0", + "@rollup/rollup-linux-arm64-musl": "4.21.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0", + "@rollup/rollup-linux-riscv64-gnu": "4.21.0", + "@rollup/rollup-linux-s390x-gnu": "4.21.0", + "@rollup/rollup-linux-x64-gnu": "4.21.0", + "@rollup/rollup-linux-x64-musl": "4.21.0", + "@rollup/rollup-win32-arm64-msvc": "4.21.0", + "@rollup/rollup-win32-ia32-msvc": "4.21.0", + "@rollup/rollup-win32-x64-msvc": "4.21.0", + "fsevents": "~2.3.2" } }, "node_modules/router": { @@ -13234,6 +16765,14 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" }, + "node_modules/search-insights": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.16.3.tgz", + "integrity": "sha512-hSHy/s4Zk2xibhj9XTCACB+1PqS+CaJxepGNBhKc/OsHRpqvHAUAm5+uZ6kJJbGXn0pb3XqekHjg6JAqPExzqg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -13416,6 +16955,17 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.14.1.tgz", + "integrity": "sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.14.1", + "@types/hast": "^3.0.4" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -13486,6 +17036,17 @@ "npm": ">= 3.0.0" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/socks": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", @@ -13678,6 +17239,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -13971,6 +17542,16 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -13999,6 +17580,69 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/stylehacks": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.3.tgz", + "integrity": "sha512-4DqtecvI/Nd+2BCvW9YEF6lhBN5UM50IJ1R3rnEAhBwbCKf4VehRf+uqvnVArnBayjYD/WtT3g0G/HSRxWfTRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -14021,6 +17665,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/synckit": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", @@ -14037,6 +17717,13 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true, + "license": "MIT" + }, "node_modules/table-layout": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", @@ -14050,6 +17737,54 @@ "node": ">=12.17" } }, + "node_modules/tailwindcss": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", + "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", @@ -14158,6 +17893,29 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -14225,6 +17983,88 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ts-morph": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-18.0.0.tgz", + "integrity": "sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.19.0", + "code-block-writer": "^12.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tsconfig-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-loader/-/tsconfig-loader-1.1.0.tgz", + "integrity": "sha512-KrFF45RYo/JHpoAp1Lf68NupYNyRmh7BwSh1AmAQ3fdCMl8laOyZSLO5iByQR2VTkVdt454HS3c5kfVeYWq7iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "deepmerge": "^4.2.2", + "json5": "^2.1.1", + "resolve": "^1.15.1", + "strip-bom": "^4.0.0" + } + }, "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", @@ -14402,6 +18242,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/typical": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", @@ -14457,6 +18312,13 @@ "node": ">=18.17" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -14505,6 +18367,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -14513,6 +18385,57 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -14534,6 +18457,13 @@ "node": ">= 0.4.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -14568,6 +18498,128 @@ "node": ">= 0.8" } }, + "node_modules/vite": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", + "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.41", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitepress": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.3.3.tgz", + "integrity": "sha512-6UzEw/wZ41S/CATby7ea7UlffvRER/uekxgN6hbEvSys9ukmLOKsz87Ehq9yOx1Rwiw+Sj97yjpivP8w1sUmng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/css": "^3.6.1", + "@docsearch/js": "^3.6.1", + "@shikijs/core": "^1.13.0", + "@shikijs/transformers": "^1.13.0", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^5.1.2", + "@vue/devtools-api": "^7.3.8", + "@vue/shared": "^3.4.38", + "@vueuse/core": "^11.0.0", + "@vueuse/integrations": "^11.0.0", + "focus-trap": "^7.5.4", + "mark.js": "8.11.1", + "minisearch": "^7.1.0", + "shiki": "^1.13.0", + "vite": "^5.4.1", + "vue": "^3.4.38" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.38.tgz", + "integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.4.38", + "@vue/compiler-sfc": "3.4.38", + "@vue/runtime-dom": "3.4.38", + "@vue/server-renderer": "3.4.38", + "@vue/shared": "3.4.38" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/walk-back": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.1.tgz", @@ -14896,6 +18948,16 @@ "node": ">= 4.0.0" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 223953e465..d419eb5ef2 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,11 @@ "npm": ">= 8" }, "scripts": { + "dev": "vitepress --open", + "build": "vitepress build", + "preview": "vitepress preview --port 8080", + "deploy": "cf push", + "gen-odata": "odata2ts", "test": "npm run lint && npm run jsdoc-generate && npm run schema-generate && npm run generate-cli-doc", "lint": "eslint ./", "jsdoc": "npm run jsdoc-generate && open-cli site/api/index.html", @@ -31,6 +36,9 @@ "jsdoc-generate-workspace": "jsdoc -c ./jsdoc-workspace.json -t $(node -p 'path.dirname(require.resolve(\"docdash\"))') ../ || (echo 'Error during JSDoc generation! Check log.' && exit 1)", "docs": "bash ./scripts/serveDocs.sh", "docs-generate": "bash ./scripts/buildDocs.sh && open-cli http://localhost:8000 && ws --compress -d site", + "docs-vitepress": "vitepress preview --port 8080", + "docs-vitepress-build": "vitepress build && vitepress preview --port 8080", + "docs:build": "vitepress build", "schema-generate": "node ./scripts/buildSchema.js ui5", "schema-workspace-generate": "node ./scripts/buildSchema.js ui5-workspace", "generate-cli-doc": "node ./scripts/generateCliDoc.js", @@ -62,6 +70,21 @@ "jsdoc": "^4.0.3", "local-web-server": "^5.4.0", "open-cli": "^8.0.0", - "traverse": "^0.6.9" + "traverse": "^0.6.9", + "@odata2ts/http-client-fetch": "^0.6.2", + "@odata2ts/odata2ts": "^0.35.0", + "@types/markdown-it-plantuml": "^1.4.5", + "@types/node": "^20.14.9", + "@ui5/webcomponents": "^1.24.5", + "autoprefixer": "^10.4.19", + "cssnano": "^7.0.3", + "markdown-it-implicit-figures": "^0.12.0", + "markdown-it-link-attributes": "^4.0.1", + "markdown-it-plantuml": "^1.4.1", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.4", + "vitepress": "^1.2.3", + "vue": "^3.4.30" + } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000000..90e7a83c5d --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,7 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}) + } +} diff --git a/resources/UI5_Tooling.graffle b/resources/UI5_Tooling.graffle deleted file mode 100644 index eb8fba8323..0000000000 Binary files a/resources/UI5_Tooling.graffle and /dev/null differ diff --git a/scripts/Dockerfile b/scripts/Dockerfile deleted file mode 100644 index e786d2a14b..0000000000 --- a/scripts/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM squidfunk/mkdocs-material:8.5.9 - -# mike version 2 is required in order to enable ENV vars for the container. By the time mike 2 is released we'll -# use a specific dev version: https://github.com/jimporter/mike/issues/125 -RUN python -m pip install 'mike @ git+https://github.com/jimporter/mike.git@e77357960886f9d9bf2e6ecbc39c7ca6991a2179' - -# Define env variables for mike -ENV GIT_COMMITTER_NAME="OpenUI5 Bot" -ENV GIT_COMMITTER_EMAIL="openui5@sap.com" diff --git a/scripts/buildDocs.sh b/scripts/buildDocs.sh deleted file mode 100755 index dfd0111002..0000000000 --- a/scripts/buildDocs.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -set -e - -cd "$(dirname -- "$0")/.." -echo "Changed directory to $(pwd)" - -# Store docker image name -DOCKER_IMAGE=ui5-tooling/mkdocs-material - -# Build image if not existing -./scripts/buildImage.sh - -npm run generate-cli-doc - - -if [[ $MIKE_VERSION ]]; then # Build with Mike (versioning) - echo "Starting building & versioning Docs with Mike version: ${MIKE_VERSION}; alias: ${MIKE_ALIAS}..." - docker run --rm -v $(pwd):/docs --entrypoint mike \ - --env GIT_COMMITTER_NAME="${GIT_COMMITTER_NAME}" --env GIT_COMMITTER_EMAIL="${GIT_COMMITTER_EMAIL}" \ - $DOCKER_IMAGE deploy $MIKE_VERSION $MIKE_ALIAS --rebase --update-aliases - -else # Build with MkDocs - echo "Starting building Docs with MkDocs..." - docker run --rm -v $(pwd):/docs $DOCKER_IMAGE build - -fi - -npm run jsdoc-generate - -echo "Documentation has been built" diff --git a/scripts/buildImage.sh b/scripts/buildImage.sh deleted file mode 100755 index b65f15737a..0000000000 --- a/scripts/buildImage.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -set -e - -cd "$(dirname -- "$0")" -echo "Changed directory to $(pwd)" - -# Store docker image name -DOCKER_IMAGE=ui5-tooling/mkdocs-material -# If Dockerfile has been modified, we need to rebuild the image -DOCKER_TAG=$(node ./hash.js ./Dockerfile) - -if [[ "$(docker images -q $DOCKER_IMAGE:$DOCKER_TAG 2> /dev/null)" != "" ]]; then - echo "Image ${DOCKER_IMAGE}:${DOCKER_TAG} already exists" - exit 0 -fi - -echo "Building image '${DOCKER_IMAGE}:${DOCKER_TAG}'..." -docker build -t $DOCKER_IMAGE -f Dockerfile . -docker tag $DOCKER_IMAGE $DOCKER_IMAGE:$DOCKER_TAG # Tag the image with Dockerfile's hash -echo "Done building image." - -exit 0 diff --git a/scripts/generateCliDoc.js b/scripts/generateCliDoc.js index eb8fb3cb54..67db10b6c0 100644 --- a/scripts/generateCliDoc.js +++ b/scripts/generateCliDoc.js @@ -111,8 +111,19 @@ function generateDoc() { if (!(obj.commands.length <= 1)) { for (const all of obj.commands) { const temp = checkChars(all); - const {command, description} = splitString(temp); - commandsObj.push({childCommand: command, commandDescription: description}); + let {command, description, details} = splitString(temp); + + // Check and remove "