13662 lines
		
	
	
		
			456 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			13662 lines
		
	
	
		
			456 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
 | |
| if you want to view the source, please visit the github repository of this plugin
 | |
| */
 | |
| 
 | |
| var __create = Object.create;
 | |
| var __defProp = Object.defineProperty;
 | |
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
 | |
| var __getOwnPropNames = Object.getOwnPropertyNames;
 | |
| var __getProtoOf = Object.getPrototypeOf;
 | |
| var __hasOwnProp = Object.prototype.hasOwnProperty;
 | |
| var __commonJS = (cb, mod) => function __require() {
 | |
|   return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
 | |
| };
 | |
| var __export = (target, all) => {
 | |
|   for (var name in all)
 | |
|     __defProp(target, name, { get: all[name], enumerable: true });
 | |
| };
 | |
| var __copyProps = (to, from, except, desc) => {
 | |
|   if (from && typeof from === "object" || typeof from === "function") {
 | |
|     for (let key of __getOwnPropNames(from))
 | |
|       if (!__hasOwnProp.call(to, key) && key !== except)
 | |
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
 | |
|   }
 | |
|   return to;
 | |
| };
 | |
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
 | |
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
 | |
| 
 | |
| // node_modules/tslib/tslib.js
 | |
| var require_tslib = __commonJS({
 | |
|   "node_modules/tslib/tslib.js"(exports, module2) {
 | |
|     var __extends2;
 | |
|     var __assign2;
 | |
|     var __rest2;
 | |
|     var __decorate2;
 | |
|     var __param2;
 | |
|     var __metadata2;
 | |
|     var __awaiter2;
 | |
|     var __generator2;
 | |
|     var __exportStar2;
 | |
|     var __values2;
 | |
|     var __read2;
 | |
|     var __spread2;
 | |
|     var __spreadArrays2;
 | |
|     var __spreadArray2;
 | |
|     var __await2;
 | |
|     var __asyncGenerator2;
 | |
|     var __asyncDelegator2;
 | |
|     var __asyncValues2;
 | |
|     var __makeTemplateObject2;
 | |
|     var __importStar2;
 | |
|     var __importDefault2;
 | |
|     var __classPrivateFieldGet7;
 | |
|     var __classPrivateFieldSet7;
 | |
|     var __classPrivateFieldIn2;
 | |
|     var __createBinding2;
 | |
|     (function(factory) {
 | |
|       var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
 | |
|       if (typeof define === "function" && define.amd) {
 | |
|         define("tslib", ["exports"], function(exports2) {
 | |
|           factory(createExporter(root, createExporter(exports2)));
 | |
|         });
 | |
|       } else if (typeof module2 === "object" && typeof module2.exports === "object") {
 | |
|         factory(createExporter(root, createExporter(module2.exports)));
 | |
|       } else {
 | |
|         factory(createExporter(root));
 | |
|       }
 | |
|       function createExporter(exports2, previous) {
 | |
|         if (exports2 !== root) {
 | |
|           if (typeof Object.create === "function") {
 | |
|             Object.defineProperty(exports2, "__esModule", { value: true });
 | |
|           } else {
 | |
|             exports2.__esModule = true;
 | |
|           }
 | |
|         }
 | |
|         return function(id, v) {
 | |
|           return exports2[id] = previous ? previous(id, v) : v;
 | |
|         };
 | |
|       }
 | |
|     })(function(exporter) {
 | |
|       var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
 | |
|         d.__proto__ = b;
 | |
|       } || function(d, b) {
 | |
|         for (var p in b)
 | |
|           if (Object.prototype.hasOwnProperty.call(b, p))
 | |
|             d[p] = b[p];
 | |
|       };
 | |
|       __extends2 = function(d, b) {
 | |
|         if (typeof b !== "function" && b !== null)
 | |
|           throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
 | |
|         extendStatics(d, b);
 | |
|         function __() {
 | |
|           this.constructor = d;
 | |
|         }
 | |
|         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
 | |
|       };
 | |
|       __assign2 = Object.assign || function(t) {
 | |
|         for (var s, i = 1, n = arguments.length; i < n; i++) {
 | |
|           s = arguments[i];
 | |
|           for (var p in s)
 | |
|             if (Object.prototype.hasOwnProperty.call(s, p))
 | |
|               t[p] = s[p];
 | |
|         }
 | |
|         return t;
 | |
|       };
 | |
|       __rest2 = function(s, e) {
 | |
|         var t = {};
 | |
|         for (var p in s)
 | |
|           if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
 | |
|             t[p] = s[p];
 | |
|         if (s != null && typeof Object.getOwnPropertySymbols === "function")
 | |
|           for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
 | |
|             if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
 | |
|               t[p[i]] = s[p[i]];
 | |
|           }
 | |
|         return t;
 | |
|       };
 | |
|       __decorate2 = function(decorators, target, key, desc) {
 | |
|         var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
 | |
|         if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
 | |
|           r = Reflect.decorate(decorators, target, key, desc);
 | |
|         else
 | |
|           for (var i = decorators.length - 1; i >= 0; i--)
 | |
|             if (d = decorators[i])
 | |
|               r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
 | |
|         return c > 3 && r && Object.defineProperty(target, key, r), r;
 | |
|       };
 | |
|       __param2 = function(paramIndex, decorator) {
 | |
|         return function(target, key) {
 | |
|           decorator(target, key, paramIndex);
 | |
|         };
 | |
|       };
 | |
|       __metadata2 = function(metadataKey, metadataValue) {
 | |
|         if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
 | |
|           return Reflect.metadata(metadataKey, metadataValue);
 | |
|       };
 | |
|       __awaiter2 = function(thisArg, _arguments, P, generator) {
 | |
|         function adopt(value) {
 | |
|           return value instanceof P ? value : new P(function(resolve) {
 | |
|             resolve(value);
 | |
|           });
 | |
|         }
 | |
|         return new (P || (P = Promise))(function(resolve, reject) {
 | |
|           function fulfilled(value) {
 | |
|             try {
 | |
|               step(generator.next(value));
 | |
|             } catch (e) {
 | |
|               reject(e);
 | |
|             }
 | |
|           }
 | |
|           function rejected(value) {
 | |
|             try {
 | |
|               step(generator["throw"](value));
 | |
|             } catch (e) {
 | |
|               reject(e);
 | |
|             }
 | |
|           }
 | |
|           function step(result) {
 | |
|             result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
 | |
|           }
 | |
|           step((generator = generator.apply(thisArg, _arguments || [])).next());
 | |
|         });
 | |
|       };
 | |
|       __generator2 = function(thisArg, body) {
 | |
|         var _ = { label: 0, sent: function() {
 | |
|           if (t[0] & 1)
 | |
|             throw t[1];
 | |
|           return t[1];
 | |
|         }, trys: [], ops: [] }, f, y, t, g;
 | |
|         return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
 | |
|           return this;
 | |
|         }), g;
 | |
|         function verb(n) {
 | |
|           return function(v) {
 | |
|             return step([n, v]);
 | |
|           };
 | |
|         }
 | |
|         function step(op) {
 | |
|           if (f)
 | |
|             throw new TypeError("Generator is already executing.");
 | |
|           while (_)
 | |
|             try {
 | |
|               if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
 | |
|                 return t;
 | |
|               if (y = 0, t)
 | |
|                 op = [op[0] & 2, t.value];
 | |
|               switch (op[0]) {
 | |
|                 case 0:
 | |
|                 case 1:
 | |
|                   t = op;
 | |
|                   break;
 | |
|                 case 4:
 | |
|                   _.label++;
 | |
|                   return { value: op[1], done: false };
 | |
|                 case 5:
 | |
|                   _.label++;
 | |
|                   y = op[1];
 | |
|                   op = [0];
 | |
|                   continue;
 | |
|                 case 7:
 | |
|                   op = _.ops.pop();
 | |
|                   _.trys.pop();
 | |
|                   continue;
 | |
|                 default:
 | |
|                   if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
 | |
|                     _ = 0;
 | |
|                     continue;
 | |
|                   }
 | |
|                   if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
 | |
|                     _.label = op[1];
 | |
|                     break;
 | |
|                   }
 | |
|                   if (op[0] === 6 && _.label < t[1]) {
 | |
|                     _.label = t[1];
 | |
|                     t = op;
 | |
|                     break;
 | |
|                   }
 | |
|                   if (t && _.label < t[2]) {
 | |
|                     _.label = t[2];
 | |
|                     _.ops.push(op);
 | |
|                     break;
 | |
|                   }
 | |
|                   if (t[2])
 | |
|                     _.ops.pop();
 | |
|                   _.trys.pop();
 | |
|                   continue;
 | |
|               }
 | |
|               op = body.call(thisArg, _);
 | |
|             } catch (e) {
 | |
|               op = [6, e];
 | |
|               y = 0;
 | |
|             } finally {
 | |
|               f = t = 0;
 | |
|             }
 | |
|           if (op[0] & 5)
 | |
|             throw op[1];
 | |
|           return { value: op[0] ? op[1] : void 0, done: true };
 | |
|         }
 | |
|       };
 | |
|       __exportStar2 = function(m, o) {
 | |
|         for (var p in m)
 | |
|           if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
 | |
|             __createBinding2(o, m, p);
 | |
|       };
 | |
|       __createBinding2 = Object.create ? function(o, m, k, k2) {
 | |
|         if (k2 === void 0)
 | |
|           k2 = k;
 | |
|         var desc = Object.getOwnPropertyDescriptor(m, k);
 | |
|         if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
 | |
|           desc = { enumerable: true, get: function() {
 | |
|             return m[k];
 | |
|           } };
 | |
|         }
 | |
|         Object.defineProperty(o, k2, desc);
 | |
|       } : function(o, m, k, k2) {
 | |
|         if (k2 === void 0)
 | |
|           k2 = k;
 | |
|         o[k2] = m[k];
 | |
|       };
 | |
|       __values2 = function(o) {
 | |
|         var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
 | |
|         if (m)
 | |
|           return m.call(o);
 | |
|         if (o && typeof o.length === "number")
 | |
|           return {
 | |
|             next: function() {
 | |
|               if (o && i >= o.length)
 | |
|                 o = void 0;
 | |
|               return { value: o && o[i++], done: !o };
 | |
|             }
 | |
|           };
 | |
|         throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
 | |
|       };
 | |
|       __read2 = function(o, n) {
 | |
|         var m = typeof Symbol === "function" && o[Symbol.iterator];
 | |
|         if (!m)
 | |
|           return o;
 | |
|         var i = m.call(o), r, ar = [], e;
 | |
|         try {
 | |
|           while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
 | |
|             ar.push(r.value);
 | |
|         } catch (error) {
 | |
|           e = { error };
 | |
|         } finally {
 | |
|           try {
 | |
|             if (r && !r.done && (m = i["return"]))
 | |
|               m.call(i);
 | |
|           } finally {
 | |
|             if (e)
 | |
|               throw e.error;
 | |
|           }
 | |
|         }
 | |
|         return ar;
 | |
|       };
 | |
|       __spread2 = function() {
 | |
|         for (var ar = [], i = 0; i < arguments.length; i++)
 | |
|           ar = ar.concat(__read2(arguments[i]));
 | |
|         return ar;
 | |
|       };
 | |
|       __spreadArrays2 = function() {
 | |
|         for (var s = 0, i = 0, il = arguments.length; i < il; i++)
 | |
|           s += arguments[i].length;
 | |
|         for (var r = Array(s), k = 0, i = 0; i < il; i++)
 | |
|           for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
 | |
|             r[k] = a[j];
 | |
|         return r;
 | |
|       };
 | |
|       __spreadArray2 = function(to, from, pack) {
 | |
|         if (pack || arguments.length === 2)
 | |
|           for (var i = 0, l = from.length, ar; i < l; i++) {
 | |
|             if (ar || !(i in from)) {
 | |
|               if (!ar)
 | |
|                 ar = Array.prototype.slice.call(from, 0, i);
 | |
|               ar[i] = from[i];
 | |
|             }
 | |
|           }
 | |
|         return to.concat(ar || Array.prototype.slice.call(from));
 | |
|       };
 | |
|       __await2 = function(v) {
 | |
|         return this instanceof __await2 ? (this.v = v, this) : new __await2(v);
 | |
|       };
 | |
|       __asyncGenerator2 = function(thisArg, _arguments, generator) {
 | |
|         if (!Symbol.asyncIterator)
 | |
|           throw new TypeError("Symbol.asyncIterator is not defined.");
 | |
|         var g = generator.apply(thisArg, _arguments || []), i, q = [];
 | |
|         return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
 | |
|           return this;
 | |
|         }, i;
 | |
|         function verb(n) {
 | |
|           if (g[n])
 | |
|             i[n] = function(v) {
 | |
|               return new Promise(function(a, b) {
 | |
|                 q.push([n, v, a, b]) > 1 || resume(n, v);
 | |
|               });
 | |
|             };
 | |
|         }
 | |
|         function resume(n, v) {
 | |
|           try {
 | |
|             step(g[n](v));
 | |
|           } catch (e) {
 | |
|             settle(q[0][3], e);
 | |
|           }
 | |
|         }
 | |
|         function step(r) {
 | |
|           r.value instanceof __await2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
 | |
|         }
 | |
|         function fulfill(value) {
 | |
|           resume("next", value);
 | |
|         }
 | |
|         function reject(value) {
 | |
|           resume("throw", value);
 | |
|         }
 | |
|         function settle(f, v) {
 | |
|           if (f(v), q.shift(), q.length)
 | |
|             resume(q[0][0], q[0][1]);
 | |
|         }
 | |
|       };
 | |
|       __asyncDelegator2 = function(o) {
 | |
|         var i, p;
 | |
|         return i = {}, verb("next"), verb("throw", function(e) {
 | |
|           throw e;
 | |
|         }), verb("return"), i[Symbol.iterator] = function() {
 | |
|           return this;
 | |
|         }, i;
 | |
|         function verb(n, f) {
 | |
|           i[n] = o[n] ? function(v) {
 | |
|             return (p = !p) ? { value: __await2(o[n](v)), done: n === "return" } : f ? f(v) : v;
 | |
|           } : f;
 | |
|         }
 | |
|       };
 | |
|       __asyncValues2 = function(o) {
 | |
|         if (!Symbol.asyncIterator)
 | |
|           throw new TypeError("Symbol.asyncIterator is not defined.");
 | |
|         var m = o[Symbol.asyncIterator], i;
 | |
|         return m ? m.call(o) : (o = typeof __values2 === "function" ? __values2(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
 | |
|           return this;
 | |
|         }, i);
 | |
|         function verb(n) {
 | |
|           i[n] = o[n] && function(v) {
 | |
|             return new Promise(function(resolve, reject) {
 | |
|               v = o[n](v), settle(resolve, reject, v.done, v.value);
 | |
|             });
 | |
|           };
 | |
|         }
 | |
|         function settle(resolve, reject, d, v) {
 | |
|           Promise.resolve(v).then(function(v2) {
 | |
|             resolve({ value: v2, done: d });
 | |
|           }, reject);
 | |
|         }
 | |
|       };
 | |
|       __makeTemplateObject2 = function(cooked, raw) {
 | |
|         if (Object.defineProperty) {
 | |
|           Object.defineProperty(cooked, "raw", { value: raw });
 | |
|         } else {
 | |
|           cooked.raw = raw;
 | |
|         }
 | |
|         return cooked;
 | |
|       };
 | |
|       var __setModuleDefault = Object.create ? function(o, v) {
 | |
|         Object.defineProperty(o, "default", { enumerable: true, value: v });
 | |
|       } : function(o, v) {
 | |
|         o["default"] = v;
 | |
|       };
 | |
|       __importStar2 = function(mod) {
 | |
|         if (mod && mod.__esModule)
 | |
|           return mod;
 | |
|         var result = {};
 | |
|         if (mod != null) {
 | |
|           for (var k in mod)
 | |
|             if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
 | |
|               __createBinding2(result, mod, k);
 | |
|         }
 | |
|         __setModuleDefault(result, mod);
 | |
|         return result;
 | |
|       };
 | |
|       __importDefault2 = function(mod) {
 | |
|         return mod && mod.__esModule ? mod : { "default": mod };
 | |
|       };
 | |
|       __classPrivateFieldGet7 = function(receiver, state, kind2, f) {
 | |
|         if (kind2 === "a" && !f)
 | |
|           throw new TypeError("Private accessor was defined without a getter");
 | |
|         if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|           throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|         return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
|       };
 | |
|       __classPrivateFieldSet7 = function(receiver, state, value, kind2, f) {
 | |
|         if (kind2 === "m")
 | |
|           throw new TypeError("Private method is not writable");
 | |
|         if (kind2 === "a" && !f)
 | |
|           throw new TypeError("Private accessor was defined without a setter");
 | |
|         if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|           throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|         return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
|       };
 | |
|       __classPrivateFieldIn2 = function(state, receiver) {
 | |
|         if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function")
 | |
|           throw new TypeError("Cannot use 'in' operator on non-object");
 | |
|         return typeof state === "function" ? receiver === state : state.has(receiver);
 | |
|       };
 | |
|       exporter("__extends", __extends2);
 | |
|       exporter("__assign", __assign2);
 | |
|       exporter("__rest", __rest2);
 | |
|       exporter("__decorate", __decorate2);
 | |
|       exporter("__param", __param2);
 | |
|       exporter("__metadata", __metadata2);
 | |
|       exporter("__awaiter", __awaiter2);
 | |
|       exporter("__generator", __generator2);
 | |
|       exporter("__exportStar", __exportStar2);
 | |
|       exporter("__createBinding", __createBinding2);
 | |
|       exporter("__values", __values2);
 | |
|       exporter("__read", __read2);
 | |
|       exporter("__spread", __spread2);
 | |
|       exporter("__spreadArrays", __spreadArrays2);
 | |
|       exporter("__spreadArray", __spreadArray2);
 | |
|       exporter("__await", __await2);
 | |
|       exporter("__asyncGenerator", __asyncGenerator2);
 | |
|       exporter("__asyncDelegator", __asyncDelegator2);
 | |
|       exporter("__asyncValues", __asyncValues2);
 | |
|       exporter("__makeTemplateObject", __makeTemplateObject2);
 | |
|       exporter("__importStar", __importStar2);
 | |
|       exporter("__importDefault", __importDefault2);
 | |
|       exporter("__classPrivateFieldGet", __classPrivateFieldGet7);
 | |
|       exporter("__classPrivateFieldSet", __classPrivateFieldSet7);
 | |
|       exporter("__classPrivateFieldIn", __classPrivateFieldIn2);
 | |
|     });
 | |
|   }
 | |
| });
 | |
| 
 | |
| // src/main.ts
 | |
| var main_exports = {};
 | |
| __export(main_exports, {
 | |
|   default: () => PodNotes
 | |
| });
 | |
| module.exports = __toCommonJS(main_exports);
 | |
| 
 | |
| // node_modules/svelte/internal/index.mjs
 | |
| function noop() {
 | |
| }
 | |
| var identity = (x) => x;
 | |
| function assign(tar, src) {
 | |
|   for (const k in src)
 | |
|     tar[k] = src[k];
 | |
|   return tar;
 | |
| }
 | |
| function is_promise(value) {
 | |
|   return value && typeof value === "object" && typeof value.then === "function";
 | |
| }
 | |
| function run(fn) {
 | |
|   return fn();
 | |
| }
 | |
| function blank_object() {
 | |
|   return /* @__PURE__ */ Object.create(null);
 | |
| }
 | |
| function run_all(fns) {
 | |
|   fns.forEach(run);
 | |
| }
 | |
| function is_function(thing) {
 | |
|   return typeof thing === "function";
 | |
| }
 | |
| function safe_not_equal(a, b) {
 | |
|   return a != a ? b == b : a !== b || (a && typeof a === "object" || typeof a === "function");
 | |
| }
 | |
| var src_url_equal_anchor;
 | |
| function src_url_equal(element_src, url) {
 | |
|   if (!src_url_equal_anchor) {
 | |
|     src_url_equal_anchor = document.createElement("a");
 | |
|   }
 | |
|   src_url_equal_anchor.href = url;
 | |
|   return element_src === src_url_equal_anchor.href;
 | |
| }
 | |
| function is_empty(obj) {
 | |
|   return Object.keys(obj).length === 0;
 | |
| }
 | |
| function subscribe(store, ...callbacks) {
 | |
|   if (store == null) {
 | |
|     return noop;
 | |
|   }
 | |
|   const unsub = store.subscribe(...callbacks);
 | |
|   return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
 | |
| }
 | |
| function get_store_value(store) {
 | |
|   let value;
 | |
|   subscribe(store, (_) => value = _)();
 | |
|   return value;
 | |
| }
 | |
| function component_subscribe(component, store, callback) {
 | |
|   component.$$.on_destroy.push(subscribe(store, callback));
 | |
| }
 | |
| function create_slot(definition, ctx, $$scope, fn) {
 | |
|   if (definition) {
 | |
|     const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
 | |
|     return definition[0](slot_ctx);
 | |
|   }
 | |
| }
 | |
| function get_slot_context(definition, ctx, $$scope, fn) {
 | |
|   return definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx;
 | |
| }
 | |
| function get_slot_changes(definition, $$scope, dirty, fn) {
 | |
|   if (definition[2] && fn) {
 | |
|     const lets = definition[2](fn(dirty));
 | |
|     if ($$scope.dirty === void 0) {
 | |
|       return lets;
 | |
|     }
 | |
|     if (typeof lets === "object") {
 | |
|       const merged = [];
 | |
|       const len = Math.max($$scope.dirty.length, lets.length);
 | |
|       for (let i = 0; i < len; i += 1) {
 | |
|         merged[i] = $$scope.dirty[i] | lets[i];
 | |
|       }
 | |
|       return merged;
 | |
|     }
 | |
|     return $$scope.dirty | lets;
 | |
|   }
 | |
|   return $$scope.dirty;
 | |
| }
 | |
| function update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {
 | |
|   if (slot_changes) {
 | |
|     const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
 | |
|     slot.p(slot_context, slot_changes);
 | |
|   }
 | |
| }
 | |
| function get_all_dirty_from_scope($$scope) {
 | |
|   if ($$scope.ctx.length > 32) {
 | |
|     const dirty = [];
 | |
|     const length = $$scope.ctx.length / 32;
 | |
|     for (let i = 0; i < length; i++) {
 | |
|       dirty[i] = -1;
 | |
|     }
 | |
|     return dirty;
 | |
|   }
 | |
|   return -1;
 | |
| }
 | |
| function null_to_empty(value) {
 | |
|   return value == null ? "" : value;
 | |
| }
 | |
| var is_client = typeof window !== "undefined";
 | |
| var now = is_client ? () => window.performance.now() : () => Date.now();
 | |
| var raf = is_client ? (cb) => requestAnimationFrame(cb) : noop;
 | |
| var tasks = /* @__PURE__ */ new Set();
 | |
| function run_tasks(now2) {
 | |
|   tasks.forEach((task) => {
 | |
|     if (!task.c(now2)) {
 | |
|       tasks.delete(task);
 | |
|       task.f();
 | |
|     }
 | |
|   });
 | |
|   if (tasks.size !== 0)
 | |
|     raf(run_tasks);
 | |
| }
 | |
| function loop(callback) {
 | |
|   let task;
 | |
|   if (tasks.size === 0)
 | |
|     raf(run_tasks);
 | |
|   return {
 | |
|     promise: new Promise((fulfill) => {
 | |
|       tasks.add(task = { c: callback, f: fulfill });
 | |
|     }),
 | |
|     abort() {
 | |
|       tasks.delete(task);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| var is_hydrating = false;
 | |
| function start_hydrating() {
 | |
|   is_hydrating = true;
 | |
| }
 | |
| function end_hydrating() {
 | |
|   is_hydrating = false;
 | |
| }
 | |
| function append(target, node) {
 | |
|   target.appendChild(node);
 | |
| }
 | |
| function append_styles(target, style_sheet_id, styles) {
 | |
|   const append_styles_to = get_root_for_style(target);
 | |
|   if (!append_styles_to.getElementById(style_sheet_id)) {
 | |
|     const style = element("style");
 | |
|     style.id = style_sheet_id;
 | |
|     style.textContent = styles;
 | |
|     append_stylesheet(append_styles_to, style);
 | |
|   }
 | |
| }
 | |
| function get_root_for_style(node) {
 | |
|   if (!node)
 | |
|     return document;
 | |
|   const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
 | |
|   if (root && root.host) {
 | |
|     return root;
 | |
|   }
 | |
|   return node.ownerDocument;
 | |
| }
 | |
| function append_empty_stylesheet(node) {
 | |
|   const style_element = element("style");
 | |
|   append_stylesheet(get_root_for_style(node), style_element);
 | |
|   return style_element.sheet;
 | |
| }
 | |
| function append_stylesheet(node, style) {
 | |
|   append(node.head || node, style);
 | |
| }
 | |
| function insert(target, node, anchor) {
 | |
|   target.insertBefore(node, anchor || null);
 | |
| }
 | |
| function detach(node) {
 | |
|   node.parentNode.removeChild(node);
 | |
| }
 | |
| function destroy_each(iterations, detaching) {
 | |
|   for (let i = 0; i < iterations.length; i += 1) {
 | |
|     if (iterations[i])
 | |
|       iterations[i].d(detaching);
 | |
|   }
 | |
| }
 | |
| function element(name) {
 | |
|   return document.createElement(name);
 | |
| }
 | |
| function text(data) {
 | |
|   return document.createTextNode(data);
 | |
| }
 | |
| function space() {
 | |
|   return text(" ");
 | |
| }
 | |
| function empty() {
 | |
|   return text("");
 | |
| }
 | |
| function listen(node, event, handler, options) {
 | |
|   node.addEventListener(event, handler, options);
 | |
|   return () => node.removeEventListener(event, handler, options);
 | |
| }
 | |
| function prevent_default(fn) {
 | |
|   return function(event) {
 | |
|     event.preventDefault();
 | |
|     return fn.call(this, event);
 | |
|   };
 | |
| }
 | |
| function attr(node, attribute, value) {
 | |
|   if (value == null)
 | |
|     node.removeAttribute(attribute);
 | |
|   else if (node.getAttribute(attribute) !== value)
 | |
|     node.setAttribute(attribute, value);
 | |
| }
 | |
| function children(element2) {
 | |
|   return Array.from(element2.childNodes);
 | |
| }
 | |
| function set_data(text2, data) {
 | |
|   data = "" + data;
 | |
|   if (text2.wholeText !== data)
 | |
|     text2.data = data;
 | |
| }
 | |
| function set_style(node, key, value, important) {
 | |
|   if (value === null) {
 | |
|     node.style.removeProperty(key);
 | |
|   } else {
 | |
|     node.style.setProperty(key, value, important ? "important" : "");
 | |
|   }
 | |
| }
 | |
| function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
 | |
|   const e = document.createEvent("CustomEvent");
 | |
|   e.initCustomEvent(type, bubbles, cancelable, detail);
 | |
|   return e;
 | |
| }
 | |
| var managed_styles = /* @__PURE__ */ new Map();
 | |
| var active = 0;
 | |
| function hash(str2) {
 | |
|   let hash2 = 5381;
 | |
|   let i = str2.length;
 | |
|   while (i--)
 | |
|     hash2 = (hash2 << 5) - hash2 ^ str2.charCodeAt(i);
 | |
|   return hash2 >>> 0;
 | |
| }
 | |
| function create_style_information(doc, node) {
 | |
|   const info = { stylesheet: append_empty_stylesheet(node), rules: {} };
 | |
|   managed_styles.set(doc, info);
 | |
|   return info;
 | |
| }
 | |
| function create_rule(node, a, b, duration2, delay, ease, fn, uid = 0) {
 | |
|   const step = 16.666 / duration2;
 | |
|   let keyframes = "{\n";
 | |
|   for (let p = 0; p <= 1; p += step) {
 | |
|     const t = a + (b - a) * ease(p);
 | |
|     keyframes += p * 100 + `%{${fn(t, 1 - t)}}
 | |
| `;
 | |
|   }
 | |
|   const rule = keyframes + `100% {${fn(b, 1 - b)}}
 | |
| }`;
 | |
|   const name = `__svelte_${hash(rule)}_${uid}`;
 | |
|   const doc = get_root_for_style(node);
 | |
|   const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);
 | |
|   if (!rules[name]) {
 | |
|     rules[name] = true;
 | |
|     stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);
 | |
|   }
 | |
|   const animation = node.style.animation || "";
 | |
|   node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration2}ms linear ${delay}ms 1 both`;
 | |
|   active += 1;
 | |
|   return name;
 | |
| }
 | |
| function delete_rule(node, name) {
 | |
|   const previous = (node.style.animation || "").split(", ");
 | |
|   const next = previous.filter(name ? (anim) => anim.indexOf(name) < 0 : (anim) => anim.indexOf("__svelte") === -1);
 | |
|   const deleted = previous.length - next.length;
 | |
|   if (deleted) {
 | |
|     node.style.animation = next.join(", ");
 | |
|     active -= deleted;
 | |
|     if (!active)
 | |
|       clear_rules();
 | |
|   }
 | |
| }
 | |
| function clear_rules() {
 | |
|   raf(() => {
 | |
|     if (active)
 | |
|       return;
 | |
|     managed_styles.forEach((info) => {
 | |
|       const { stylesheet } = info;
 | |
|       let i = stylesheet.cssRules.length;
 | |
|       while (i--)
 | |
|         stylesheet.deleteRule(i);
 | |
|       info.rules = {};
 | |
|     });
 | |
|     managed_styles.clear();
 | |
|   });
 | |
| }
 | |
| var current_component;
 | |
| function set_current_component(component) {
 | |
|   current_component = component;
 | |
| }
 | |
| function get_current_component() {
 | |
|   if (!current_component)
 | |
|     throw new Error("Function called outside component initialization");
 | |
|   return current_component;
 | |
| }
 | |
| function onMount(fn) {
 | |
|   get_current_component().$$.on_mount.push(fn);
 | |
| }
 | |
| function afterUpdate(fn) {
 | |
|   get_current_component().$$.after_update.push(fn);
 | |
| }
 | |
| function onDestroy(fn) {
 | |
|   get_current_component().$$.on_destroy.push(fn);
 | |
| }
 | |
| function createEventDispatcher() {
 | |
|   const component = get_current_component();
 | |
|   return (type, detail, { cancelable = false } = {}) => {
 | |
|     const callbacks = component.$$.callbacks[type];
 | |
|     if (callbacks) {
 | |
|       const event = custom_event(type, detail, { cancelable });
 | |
|       callbacks.slice().forEach((fn) => {
 | |
|         fn.call(component, event);
 | |
|       });
 | |
|       return !event.defaultPrevented;
 | |
|     }
 | |
|     return true;
 | |
|   };
 | |
| }
 | |
| function bubble(component, event) {
 | |
|   const callbacks = component.$$.callbacks[event.type];
 | |
|   if (callbacks) {
 | |
|     callbacks.slice().forEach((fn) => fn.call(this, event));
 | |
|   }
 | |
| }
 | |
| var dirty_components = [];
 | |
| var binding_callbacks = [];
 | |
| var render_callbacks = [];
 | |
| var flush_callbacks = [];
 | |
| var resolved_promise = Promise.resolve();
 | |
| var update_scheduled = false;
 | |
| function schedule_update() {
 | |
|   if (!update_scheduled) {
 | |
|     update_scheduled = true;
 | |
|     resolved_promise.then(flush);
 | |
|   }
 | |
| }
 | |
| function add_render_callback(fn) {
 | |
|   render_callbacks.push(fn);
 | |
| }
 | |
| function add_flush_callback(fn) {
 | |
|   flush_callbacks.push(fn);
 | |
| }
 | |
| var seen_callbacks = /* @__PURE__ */ new Set();
 | |
| var flushidx = 0;
 | |
| function flush() {
 | |
|   const saved_component = current_component;
 | |
|   do {
 | |
|     while (flushidx < dirty_components.length) {
 | |
|       const component = dirty_components[flushidx];
 | |
|       flushidx++;
 | |
|       set_current_component(component);
 | |
|       update(component.$$);
 | |
|     }
 | |
|     set_current_component(null);
 | |
|     dirty_components.length = 0;
 | |
|     flushidx = 0;
 | |
|     while (binding_callbacks.length)
 | |
|       binding_callbacks.pop()();
 | |
|     for (let i = 0; i < render_callbacks.length; i += 1) {
 | |
|       const callback = render_callbacks[i];
 | |
|       if (!seen_callbacks.has(callback)) {
 | |
|         seen_callbacks.add(callback);
 | |
|         callback();
 | |
|       }
 | |
|     }
 | |
|     render_callbacks.length = 0;
 | |
|   } while (dirty_components.length);
 | |
|   while (flush_callbacks.length) {
 | |
|     flush_callbacks.pop()();
 | |
|   }
 | |
|   update_scheduled = false;
 | |
|   seen_callbacks.clear();
 | |
|   set_current_component(saved_component);
 | |
| }
 | |
| function update($$) {
 | |
|   if ($$.fragment !== null) {
 | |
|     $$.update();
 | |
|     run_all($$.before_update);
 | |
|     const dirty = $$.dirty;
 | |
|     $$.dirty = [-1];
 | |
|     $$.fragment && $$.fragment.p($$.ctx, dirty);
 | |
|     $$.after_update.forEach(add_render_callback);
 | |
|   }
 | |
| }
 | |
| var promise;
 | |
| function wait() {
 | |
|   if (!promise) {
 | |
|     promise = Promise.resolve();
 | |
|     promise.then(() => {
 | |
|       promise = null;
 | |
|     });
 | |
|   }
 | |
|   return promise;
 | |
| }
 | |
| function dispatch(node, direction, kind2) {
 | |
|   node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind2}`));
 | |
| }
 | |
| var outroing = /* @__PURE__ */ new Set();
 | |
| var outros;
 | |
| function group_outros() {
 | |
|   outros = {
 | |
|     r: 0,
 | |
|     c: [],
 | |
|     p: outros
 | |
|   };
 | |
| }
 | |
| function check_outros() {
 | |
|   if (!outros.r) {
 | |
|     run_all(outros.c);
 | |
|   }
 | |
|   outros = outros.p;
 | |
| }
 | |
| function transition_in(block, local) {
 | |
|   if (block && block.i) {
 | |
|     outroing.delete(block);
 | |
|     block.i(local);
 | |
|   }
 | |
| }
 | |
| function transition_out(block, local, detach2, callback) {
 | |
|   if (block && block.o) {
 | |
|     if (outroing.has(block))
 | |
|       return;
 | |
|     outroing.add(block);
 | |
|     outros.c.push(() => {
 | |
|       outroing.delete(block);
 | |
|       if (callback) {
 | |
|         if (detach2)
 | |
|           block.d(1);
 | |
|         callback();
 | |
|       }
 | |
|     });
 | |
|     block.o(local);
 | |
|   } else if (callback) {
 | |
|     callback();
 | |
|   }
 | |
| }
 | |
| var null_transition = { duration: 0 };
 | |
| function create_bidirectional_transition(node, fn, params, intro) {
 | |
|   let config = fn(node, params);
 | |
|   let t = intro ? 0 : 1;
 | |
|   let running_program = null;
 | |
|   let pending_program = null;
 | |
|   let animation_name = null;
 | |
|   function clear_animation() {
 | |
|     if (animation_name)
 | |
|       delete_rule(node, animation_name);
 | |
|   }
 | |
|   function init2(program, duration2) {
 | |
|     const d = program.b - t;
 | |
|     duration2 *= Math.abs(d);
 | |
|     return {
 | |
|       a: t,
 | |
|       b: program.b,
 | |
|       d,
 | |
|       duration: duration2,
 | |
|       start: program.start,
 | |
|       end: program.start + duration2,
 | |
|       group: program.group
 | |
|     };
 | |
|   }
 | |
|   function go(b) {
 | |
|     const { delay = 0, duration: duration2 = 300, easing = identity, tick: tick2 = noop, css } = config || null_transition;
 | |
|     const program = {
 | |
|       start: now() + delay,
 | |
|       b
 | |
|     };
 | |
|     if (!b) {
 | |
|       program.group = outros;
 | |
|       outros.r += 1;
 | |
|     }
 | |
|     if (running_program || pending_program) {
 | |
|       pending_program = program;
 | |
|     } else {
 | |
|       if (css) {
 | |
|         clear_animation();
 | |
|         animation_name = create_rule(node, t, b, duration2, delay, easing, css);
 | |
|       }
 | |
|       if (b)
 | |
|         tick2(0, 1);
 | |
|       running_program = init2(program, duration2);
 | |
|       add_render_callback(() => dispatch(node, b, "start"));
 | |
|       loop((now2) => {
 | |
|         if (pending_program && now2 > pending_program.start) {
 | |
|           running_program = init2(pending_program, duration2);
 | |
|           pending_program = null;
 | |
|           dispatch(node, running_program.b, "start");
 | |
|           if (css) {
 | |
|             clear_animation();
 | |
|             animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);
 | |
|           }
 | |
|         }
 | |
|         if (running_program) {
 | |
|           if (now2 >= running_program.end) {
 | |
|             tick2(t = running_program.b, 1 - t);
 | |
|             dispatch(node, running_program.b, "end");
 | |
|             if (!pending_program) {
 | |
|               if (running_program.b) {
 | |
|                 clear_animation();
 | |
|               } else {
 | |
|                 if (!--running_program.group.r)
 | |
|                   run_all(running_program.group.c);
 | |
|               }
 | |
|             }
 | |
|             running_program = null;
 | |
|           } else if (now2 >= running_program.start) {
 | |
|             const p = now2 - running_program.start;
 | |
|             t = running_program.a + running_program.d * easing(p / running_program.duration);
 | |
|             tick2(t, 1 - t);
 | |
|           }
 | |
|         }
 | |
|         return !!(running_program || pending_program);
 | |
|       });
 | |
|     }
 | |
|   }
 | |
|   return {
 | |
|     run(b) {
 | |
|       if (is_function(config)) {
 | |
|         wait().then(() => {
 | |
|           config = config();
 | |
|           go(b);
 | |
|         });
 | |
|       } else {
 | |
|         go(b);
 | |
|       }
 | |
|     },
 | |
|     end() {
 | |
|       clear_animation();
 | |
|       running_program = pending_program = null;
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function handle_promise(promise2, info) {
 | |
|   const token = info.token = {};
 | |
|   function update2(type, index, key, value) {
 | |
|     if (info.token !== token)
 | |
|       return;
 | |
|     info.resolved = value;
 | |
|     let child_ctx = info.ctx;
 | |
|     if (key !== void 0) {
 | |
|       child_ctx = child_ctx.slice();
 | |
|       child_ctx[key] = value;
 | |
|     }
 | |
|     const block = type && (info.current = type)(child_ctx);
 | |
|     let needs_flush = false;
 | |
|     if (info.block) {
 | |
|       if (info.blocks) {
 | |
|         info.blocks.forEach((block2, i) => {
 | |
|           if (i !== index && block2) {
 | |
|             group_outros();
 | |
|             transition_out(block2, 1, 1, () => {
 | |
|               if (info.blocks[i] === block2) {
 | |
|                 info.blocks[i] = null;
 | |
|               }
 | |
|             });
 | |
|             check_outros();
 | |
|           }
 | |
|         });
 | |
|       } else {
 | |
|         info.block.d(1);
 | |
|       }
 | |
|       block.c();
 | |
|       transition_in(block, 1);
 | |
|       block.m(info.mount(), info.anchor);
 | |
|       needs_flush = true;
 | |
|     }
 | |
|     info.block = block;
 | |
|     if (info.blocks)
 | |
|       info.blocks[index] = block;
 | |
|     if (needs_flush) {
 | |
|       flush();
 | |
|     }
 | |
|   }
 | |
|   if (is_promise(promise2)) {
 | |
|     const current_component2 = get_current_component();
 | |
|     promise2.then((value) => {
 | |
|       set_current_component(current_component2);
 | |
|       update2(info.then, 1, info.value, value);
 | |
|       set_current_component(null);
 | |
|     }, (error) => {
 | |
|       set_current_component(current_component2);
 | |
|       update2(info.catch, 2, info.error, error);
 | |
|       set_current_component(null);
 | |
|       if (!info.hasCatch) {
 | |
|         throw error;
 | |
|       }
 | |
|     });
 | |
|     if (info.current !== info.pending) {
 | |
|       update2(info.pending, 0);
 | |
|       return true;
 | |
|     }
 | |
|   } else {
 | |
|     if (info.current !== info.then) {
 | |
|       update2(info.then, 1, info.value, promise2);
 | |
|       return true;
 | |
|     }
 | |
|     info.resolved = promise2;
 | |
|   }
 | |
| }
 | |
| function update_await_block_branch(info, ctx, dirty) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   const { resolved } = info;
 | |
|   if (info.current === info.then) {
 | |
|     child_ctx[info.value] = resolved;
 | |
|   }
 | |
|   if (info.current === info.catch) {
 | |
|     child_ctx[info.error] = resolved;
 | |
|   }
 | |
|   info.block.p(child_ctx, dirty);
 | |
| }
 | |
| var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : global;
 | |
| function outro_and_destroy_block(block, lookup) {
 | |
|   transition_out(block, 1, 1, () => {
 | |
|     lookup.delete(block.key);
 | |
|   });
 | |
| }
 | |
| function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block5, next, get_context) {
 | |
|   let o = old_blocks.length;
 | |
|   let n = list.length;
 | |
|   let i = o;
 | |
|   const old_indexes = {};
 | |
|   while (i--)
 | |
|     old_indexes[old_blocks[i].key] = i;
 | |
|   const new_blocks = [];
 | |
|   const new_lookup = /* @__PURE__ */ new Map();
 | |
|   const deltas = /* @__PURE__ */ new Map();
 | |
|   i = n;
 | |
|   while (i--) {
 | |
|     const child_ctx = get_context(ctx, list, i);
 | |
|     const key = get_key(child_ctx);
 | |
|     let block = lookup.get(key);
 | |
|     if (!block) {
 | |
|       block = create_each_block5(key, child_ctx);
 | |
|       block.c();
 | |
|     } else if (dynamic) {
 | |
|       block.p(child_ctx, dirty);
 | |
|     }
 | |
|     new_lookup.set(key, new_blocks[i] = block);
 | |
|     if (key in old_indexes)
 | |
|       deltas.set(key, Math.abs(i - old_indexes[key]));
 | |
|   }
 | |
|   const will_move = /* @__PURE__ */ new Set();
 | |
|   const did_move = /* @__PURE__ */ new Set();
 | |
|   function insert2(block) {
 | |
|     transition_in(block, 1);
 | |
|     block.m(node, next);
 | |
|     lookup.set(block.key, block);
 | |
|     next = block.first;
 | |
|     n--;
 | |
|   }
 | |
|   while (o && n) {
 | |
|     const new_block = new_blocks[n - 1];
 | |
|     const old_block = old_blocks[o - 1];
 | |
|     const new_key = new_block.key;
 | |
|     const old_key = old_block.key;
 | |
|     if (new_block === old_block) {
 | |
|       next = new_block.first;
 | |
|       o--;
 | |
|       n--;
 | |
|     } else if (!new_lookup.has(old_key)) {
 | |
|       destroy(old_block, lookup);
 | |
|       o--;
 | |
|     } else if (!lookup.has(new_key) || will_move.has(new_key)) {
 | |
|       insert2(new_block);
 | |
|     } else if (did_move.has(old_key)) {
 | |
|       o--;
 | |
|     } else if (deltas.get(new_key) > deltas.get(old_key)) {
 | |
|       did_move.add(new_key);
 | |
|       insert2(new_block);
 | |
|     } else {
 | |
|       will_move.add(old_key);
 | |
|       o--;
 | |
|     }
 | |
|   }
 | |
|   while (o--) {
 | |
|     const old_block = old_blocks[o];
 | |
|     if (!new_lookup.has(old_block.key))
 | |
|       destroy(old_block, lookup);
 | |
|   }
 | |
|   while (n)
 | |
|     insert2(new_blocks[n - 1]);
 | |
|   return new_blocks;
 | |
| }
 | |
| function bind(component, name, callback) {
 | |
|   const index = component.$$.props[name];
 | |
|   if (index !== void 0) {
 | |
|     component.$$.bound[index] = callback;
 | |
|     callback(component.$$.ctx[index]);
 | |
|   }
 | |
| }
 | |
| function create_component(block) {
 | |
|   block && block.c();
 | |
| }
 | |
| function mount_component(component, target, anchor, customElement) {
 | |
|   const { fragment, on_mount, on_destroy, after_update } = component.$$;
 | |
|   fragment && fragment.m(target, anchor);
 | |
|   if (!customElement) {
 | |
|     add_render_callback(() => {
 | |
|       const new_on_destroy = on_mount.map(run).filter(is_function);
 | |
|       if (on_destroy) {
 | |
|         on_destroy.push(...new_on_destroy);
 | |
|       } else {
 | |
|         run_all(new_on_destroy);
 | |
|       }
 | |
|       component.$$.on_mount = [];
 | |
|     });
 | |
|   }
 | |
|   after_update.forEach(add_render_callback);
 | |
| }
 | |
| function destroy_component(component, detaching) {
 | |
|   const $$ = component.$$;
 | |
|   if ($$.fragment !== null) {
 | |
|     run_all($$.on_destroy);
 | |
|     $$.fragment && $$.fragment.d(detaching);
 | |
|     $$.on_destroy = $$.fragment = null;
 | |
|     $$.ctx = [];
 | |
|   }
 | |
| }
 | |
| function make_dirty(component, i) {
 | |
|   if (component.$$.dirty[0] === -1) {
 | |
|     dirty_components.push(component);
 | |
|     schedule_update();
 | |
|     component.$$.dirty.fill(0);
 | |
|   }
 | |
|   component.$$.dirty[i / 31 | 0] |= 1 << i % 31;
 | |
| }
 | |
| function init(component, options, instance23, create_fragment24, not_equal, props, append_styles2, dirty = [-1]) {
 | |
|   const parent_component = current_component;
 | |
|   set_current_component(component);
 | |
|   const $$ = component.$$ = {
 | |
|     fragment: null,
 | |
|     ctx: null,
 | |
|     props,
 | |
|     update: noop,
 | |
|     not_equal,
 | |
|     bound: blank_object(),
 | |
|     on_mount: [],
 | |
|     on_destroy: [],
 | |
|     on_disconnect: [],
 | |
|     before_update: [],
 | |
|     after_update: [],
 | |
|     context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
 | |
|     callbacks: blank_object(),
 | |
|     dirty,
 | |
|     skip_bound: false,
 | |
|     root: options.target || parent_component.$$.root
 | |
|   };
 | |
|   append_styles2 && append_styles2($$.root);
 | |
|   let ready = false;
 | |
|   $$.ctx = instance23 ? instance23(component, options.props || {}, (i, ret, ...rest) => {
 | |
|     const value = rest.length ? rest[0] : ret;
 | |
|     if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
 | |
|       if (!$$.skip_bound && $$.bound[i])
 | |
|         $$.bound[i](value);
 | |
|       if (ready)
 | |
|         make_dirty(component, i);
 | |
|     }
 | |
|     return ret;
 | |
|   }) : [];
 | |
|   $$.update();
 | |
|   ready = true;
 | |
|   run_all($$.before_update);
 | |
|   $$.fragment = create_fragment24 ? create_fragment24($$.ctx) : false;
 | |
|   if (options.target) {
 | |
|     if (options.hydrate) {
 | |
|       start_hydrating();
 | |
|       const nodes = children(options.target);
 | |
|       $$.fragment && $$.fragment.l(nodes);
 | |
|       nodes.forEach(detach);
 | |
|     } else {
 | |
|       $$.fragment && $$.fragment.c();
 | |
|     }
 | |
|     if (options.intro)
 | |
|       transition_in(component.$$.fragment);
 | |
|     mount_component(component, options.target, options.anchor, options.customElement);
 | |
|     end_hydrating();
 | |
|     flush();
 | |
|   }
 | |
|   set_current_component(parent_component);
 | |
| }
 | |
| var SvelteElement;
 | |
| if (typeof HTMLElement === "function") {
 | |
|   SvelteElement = class extends HTMLElement {
 | |
|     constructor() {
 | |
|       super();
 | |
|       this.attachShadow({ mode: "open" });
 | |
|     }
 | |
|     connectedCallback() {
 | |
|       const { on_mount } = this.$$;
 | |
|       this.$$.on_disconnect = on_mount.map(run).filter(is_function);
 | |
|       for (const key in this.$$.slotted) {
 | |
|         this.appendChild(this.$$.slotted[key]);
 | |
|       }
 | |
|     }
 | |
|     attributeChangedCallback(attr2, _oldValue, newValue) {
 | |
|       this[attr2] = newValue;
 | |
|     }
 | |
|     disconnectedCallback() {
 | |
|       run_all(this.$$.on_disconnect);
 | |
|     }
 | |
|     $destroy() {
 | |
|       destroy_component(this, 1);
 | |
|       this.$destroy = noop;
 | |
|     }
 | |
|     $on(type, callback) {
 | |
|       const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
 | |
|       callbacks.push(callback);
 | |
|       return () => {
 | |
|         const index = callbacks.indexOf(callback);
 | |
|         if (index !== -1)
 | |
|           callbacks.splice(index, 1);
 | |
|       };
 | |
|     }
 | |
|     $set($$props) {
 | |
|       if (this.$$set && !is_empty($$props)) {
 | |
|         this.$$.skip_bound = true;
 | |
|         this.$$set($$props);
 | |
|         this.$$.skip_bound = false;
 | |
|       }
 | |
|     }
 | |
|   };
 | |
| }
 | |
| var SvelteComponent = class {
 | |
|   $destroy() {
 | |
|     destroy_component(this, 1);
 | |
|     this.$destroy = noop;
 | |
|   }
 | |
|   $on(type, callback) {
 | |
|     const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
 | |
|     callbacks.push(callback);
 | |
|     return () => {
 | |
|       const index = callbacks.indexOf(callback);
 | |
|       if (index !== -1)
 | |
|         callbacks.splice(index, 1);
 | |
|     };
 | |
|   }
 | |
|   $set($$props) {
 | |
|     if (this.$$set && !is_empty($$props)) {
 | |
|       this.$$.skip_bound = true;
 | |
|       this.$$set($$props);
 | |
|       this.$$.skip_bound = false;
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/svelte/store/index.mjs
 | |
| var subscriber_queue = [];
 | |
| function writable(value, start = noop) {
 | |
|   let stop;
 | |
|   const subscribers = /* @__PURE__ */ new Set();
 | |
|   function set(new_value) {
 | |
|     if (safe_not_equal(value, new_value)) {
 | |
|       value = new_value;
 | |
|       if (stop) {
 | |
|         const run_queue = !subscriber_queue.length;
 | |
|         for (const subscriber of subscribers) {
 | |
|           subscriber[1]();
 | |
|           subscriber_queue.push(subscriber, value);
 | |
|         }
 | |
|         if (run_queue) {
 | |
|           for (let i = 0; i < subscriber_queue.length; i += 2) {
 | |
|             subscriber_queue[i][0](subscriber_queue[i + 1]);
 | |
|           }
 | |
|           subscriber_queue.length = 0;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   function update2(fn) {
 | |
|     set(fn(value));
 | |
|   }
 | |
|   function subscribe2(run2, invalidate = noop) {
 | |
|     const subscriber = [run2, invalidate];
 | |
|     subscribers.add(subscriber);
 | |
|     if (subscribers.size === 1) {
 | |
|       stop = start(set) || noop;
 | |
|     }
 | |
|     run2(value);
 | |
|     return () => {
 | |
|       subscribers.delete(subscriber);
 | |
|       if (subscribers.size === 0) {
 | |
|         stop();
 | |
|         stop = null;
 | |
|       }
 | |
|     };
 | |
|   }
 | |
|   return { set, update: update2, subscribe: subscribe2 };
 | |
| }
 | |
| 
 | |
| // src/store/index.ts
 | |
| var import_obsidian = require("obsidian");
 | |
| var plugin = writable();
 | |
| var currentTime = writable(0);
 | |
| var duration = writable(0);
 | |
| var currentEpisode = (() => {
 | |
|   const store = writable();
 | |
|   const { subscribe: subscribe2, update: update2 } = store;
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     update: update2,
 | |
|     set: (newEpisode, addPrevToQueue = true) => {
 | |
|       update2((previousEpisode) => {
 | |
|         if (previousEpisode) {
 | |
|           if (addPrevToQueue) {
 | |
|             addEpisodeToQueue(previousEpisode);
 | |
|           }
 | |
|           const ct = get_store_value(currentTime);
 | |
|           const dur = get_store_value(duration);
 | |
|           const isFinished = ct === dur;
 | |
|           playedEpisodes.setEpisodeTime(previousEpisode, ct, dur, isFinished);
 | |
|         }
 | |
|         return newEpisode;
 | |
|       });
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| var isPaused = writable(true);
 | |
| var playedEpisodes = (() => {
 | |
|   const store = writable({});
 | |
|   const { subscribe: subscribe2, update: update2, set } = store;
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     set,
 | |
|     update: update2,
 | |
|     setEpisodeTime: (episode, time, duration2, finished) => {
 | |
|       update2((playedEpisodes2) => {
 | |
|         playedEpisodes2[episode.title] = {
 | |
|           title: episode.title,
 | |
|           podcastName: episode.podcastName,
 | |
|           time,
 | |
|           duration: duration2,
 | |
|           finished
 | |
|         };
 | |
|         return playedEpisodes2;
 | |
|       });
 | |
|     },
 | |
|     markAsPlayed: (episode) => {
 | |
|       update2((playedEpisodes2) => {
 | |
|         const playedEpisode = playedEpisodes2[episode.title] || episode;
 | |
|         if (playedEpisode) {
 | |
|           playedEpisode.time = playedEpisode.duration;
 | |
|           playedEpisode.finished = true;
 | |
|         }
 | |
|         playedEpisodes2[episode.title] = playedEpisode;
 | |
|         return playedEpisodes2;
 | |
|       });
 | |
|     },
 | |
|     markAsUnplayed: (episode) => {
 | |
|       update2((playedEpisodes2) => {
 | |
|         const playedEpisode = playedEpisodes2[episode.title] || episode;
 | |
|         if (playedEpisode) {
 | |
|           playedEpisode.time = 0;
 | |
|           playedEpisode.finished = false;
 | |
|         }
 | |
|         playedEpisodes2[episode.title] = playedEpisode;
 | |
|         return playedEpisodes2;
 | |
|       });
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| var podcastsUpdated = writable(0);
 | |
| var savedFeeds = writable({});
 | |
| var episodeCache = writable({});
 | |
| var downloadedEpisodes = (() => {
 | |
|   const store = writable({});
 | |
|   const { subscribe: subscribe2, update: update2, set } = store;
 | |
|   function isEpisodeDownloaded(episode) {
 | |
|     return get_store_value(store)[episode.podcastName]?.some((e) => e.title === episode.title);
 | |
|   }
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     set,
 | |
|     update: update2,
 | |
|     isEpisodeDownloaded,
 | |
|     addEpisode: (episode, filePath, size) => {
 | |
|       update2((downloadedEpisodes2) => {
 | |
|         const podcastEpisodes = downloadedEpisodes2[episode.podcastName] || [];
 | |
|         const idx = podcastEpisodes.findIndex((ep) => ep.title === episode.title);
 | |
|         if (idx !== -1) {
 | |
|           podcastEpisodes[idx] = { ...episode, filePath, size };
 | |
|         } else {
 | |
|           podcastEpisodes.push({
 | |
|             ...episode,
 | |
|             filePath,
 | |
|             size
 | |
|           });
 | |
|         }
 | |
|         downloadedEpisodes2[episode.podcastName] = podcastEpisodes;
 | |
|         return downloadedEpisodes2;
 | |
|       });
 | |
|     },
 | |
|     removeEpisode: (episode, removeFile) => {
 | |
|       update2((downloadedEpisodes2) => {
 | |
|         const podcastEpisodes = downloadedEpisodes2[episode.podcastName] || [];
 | |
|         const index = podcastEpisodes.findIndex((e) => e.title === episode.title);
 | |
|         const filePath = podcastEpisodes[index].filePath;
 | |
|         podcastEpisodes.splice(index, 1);
 | |
|         if (removeFile) {
 | |
|           try {
 | |
|             const file = app.vault.getAbstractFileByPath(filePath);
 | |
|             if (file instanceof import_obsidian.TFile) {
 | |
|               app.vault.delete(file);
 | |
|             }
 | |
|           } catch (error) {
 | |
|             console.error(error);
 | |
|           }
 | |
|         }
 | |
|         downloadedEpisodes2[episode.podcastName] = podcastEpisodes;
 | |
|         return downloadedEpisodes2;
 | |
|       });
 | |
|     },
 | |
|     getEpisode: (episode) => {
 | |
|       return get_store_value(store)[episode.podcastName]?.find((e) => e.title === episode.title);
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| var queue = (() => {
 | |
|   const store = writable({
 | |
|     icon: "list-ordered",
 | |
|     name: "Queue",
 | |
|     episodes: [],
 | |
|     shouldEpisodeRemoveAfterPlay: true,
 | |
|     shouldRepeat: false
 | |
|   });
 | |
|   const { subscribe: subscribe2, update: update2, set } = store;
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     update: update2,
 | |
|     set,
 | |
|     add: (episode) => {
 | |
|       update2((queue2) => {
 | |
|         queue2.episodes.push(episode);
 | |
|         return queue2;
 | |
|       });
 | |
|     },
 | |
|     remove: (episode) => {
 | |
|       update2((queue2) => {
 | |
|         queue2.episodes = queue2.episodes.filter((e) => e.title !== episode.title);
 | |
|         return queue2;
 | |
|       });
 | |
|     },
 | |
|     playNext: () => {
 | |
|       update2((queue2) => {
 | |
|         const nextEp = queue2.episodes.shift();
 | |
|         if (nextEp) {
 | |
|           currentEpisode.set(nextEp, false);
 | |
|         }
 | |
|         return queue2;
 | |
|       });
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| var favorites = writable({
 | |
|   icon: "lucide-star",
 | |
|   name: "Favorites",
 | |
|   episodes: [],
 | |
|   shouldEpisodeRemoveAfterPlay: false,
 | |
|   shouldRepeat: false
 | |
| });
 | |
| var localFiles = (() => {
 | |
|   const store = writable({
 | |
|     icon: "folder",
 | |
|     name: "Local Files",
 | |
|     episodes: [],
 | |
|     shouldEpisodeRemoveAfterPlay: false,
 | |
|     shouldRepeat: false
 | |
|   });
 | |
|   const { subscribe: subscribe2, update: update2, set } = store;
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     update: update2,
 | |
|     set,
 | |
|     getLocalEpisode: (title) => {
 | |
|       const ep = get_store_value(store).episodes.find((ep2) => ep2.title === title);
 | |
|       return ep;
 | |
|     },
 | |
|     updateStreamUrl: (title, newUrl) => {
 | |
|       store.update((playlist) => {
 | |
|         const idx = playlist.episodes.findIndex((ep) => ep.title === title);
 | |
|         if (idx !== -1)
 | |
|           playlist.episodes[idx].streamUrl = newUrl;
 | |
|         return playlist;
 | |
|       });
 | |
|     },
 | |
|     addEpisode: (episode) => {
 | |
|       store.update((playlist) => {
 | |
|         const idx = playlist.episodes.findIndex((ep) => ep.title === episode.title);
 | |
|         if (idx !== -1) {
 | |
|           playlist.episodes[idx] = episode;
 | |
|         } else {
 | |
|           playlist.episodes.push(episode);
 | |
|         }
 | |
|         return playlist;
 | |
|       });
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| var playlists = writable({});
 | |
| var podcastView = writable();
 | |
| var viewState = (() => {
 | |
|   const store = writable(0 /* PodcastGrid */);
 | |
|   const { subscribe: subscribe2, set } = store;
 | |
|   return {
 | |
|     subscribe: subscribe2,
 | |
|     set: (newState) => {
 | |
|       set(newState);
 | |
|       get_store_value(podcastView)?.scrollIntoView();
 | |
|     }
 | |
|   };
 | |
| })();
 | |
| function addEpisodeToQueue(episode) {
 | |
|   queue.update((playlist) => {
 | |
|     const newEpisodes = [episode, ...playlist.episodes];
 | |
|     playlist.episodes = newEpisodes;
 | |
|     return playlist;
 | |
|   });
 | |
| }
 | |
| 
 | |
| // src/main.ts
 | |
| var import_obsidian24 = require("obsidian");
 | |
| 
 | |
| // src/utility/formatSeconds.ts
 | |
| function formatSeconds(seconds, format2) {
 | |
|   return window.moment().startOf("day").seconds(seconds).format(format2);
 | |
| }
 | |
| 
 | |
| // src/utility/encodePodnotesURI.ts
 | |
| function encodePodnotesURI(title, feedUrl, time) {
 | |
|   const url = new URL(`obsidian://podnotes`);
 | |
|   url.searchParams.set("episodeName", title);
 | |
|   url.searchParams.set("url", feedUrl);
 | |
|   if (time) {
 | |
|     url.searchParams.set("time", time.toString());
 | |
|   }
 | |
|   return url;
 | |
| }
 | |
| 
 | |
| // src/utility/isLocalFile.ts
 | |
| function isLocalFile(ep) {
 | |
|   return ep.podcastName === "local file";
 | |
| }
 | |
| 
 | |
| // src/API/API.ts
 | |
| var API = class {
 | |
|   get podcast() {
 | |
|     return get_store_value(currentEpisode);
 | |
|   }
 | |
|   get length() {
 | |
|     return get_store_value(duration);
 | |
|   }
 | |
|   get currentTime() {
 | |
|     return get_store_value(currentTime);
 | |
|   }
 | |
|   set currentTime(value) {
 | |
|     currentTime.update((_) => value);
 | |
|   }
 | |
|   get isPlaying() {
 | |
|     return !get_store_value(isPaused);
 | |
|   }
 | |
|   getPodcastTimeFormatted(format2, linkify = false) {
 | |
|     if (!this.podcast) {
 | |
|       throw new Error("No podcast loaded");
 | |
|     }
 | |
|     const time = formatSeconds(this.currentTime, format2);
 | |
|     if (!linkify)
 | |
|       return time;
 | |
|     const epIsLocal = isLocalFile(this.podcast);
 | |
|     const feedUrl = !epIsLocal ? this.podcast.feedUrl : downloadedEpisodes.getEpisode(this.podcast)?.filePath;
 | |
|     if (!feedUrl || feedUrl === "") {
 | |
|       return time;
 | |
|     }
 | |
|     const url = encodePodnotesURI(this.podcast.title, feedUrl, this.currentTime);
 | |
|     return `[${time}](${url.href})`;
 | |
|   }
 | |
|   start() {
 | |
|     isPaused.update((_) => false);
 | |
|   }
 | |
|   stop() {
 | |
|     isPaused.update((_) => true);
 | |
|   }
 | |
|   togglePlayback() {
 | |
|     isPaused.update((isPaused2) => !isPaused2);
 | |
|   }
 | |
|   skipBackward() {
 | |
|     const skipBackLen = get_store_value(plugin).settings.skipBackwardLength;
 | |
|     this.currentTime -= skipBackLen;
 | |
|   }
 | |
|   skipForward() {
 | |
|     const skipForwardLen = get_store_value(plugin).settings.skipForwardLength;
 | |
|     this.currentTime += skipForwardLen;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/constants.ts
 | |
| var VIEW_TYPE = "podcast_player_view";
 | |
| var FAVORITES_SETTINGS = {
 | |
|   icon: "lucide-star",
 | |
|   name: "Favorites",
 | |
|   shouldEpisodeRemoveAfterPlay: false,
 | |
|   shouldRepeat: false
 | |
| };
 | |
| var QUEUE_SETTINGS = {
 | |
|   icon: "list-ordered",
 | |
|   name: "Queue",
 | |
|   shouldEpisodeRemoveAfterPlay: true,
 | |
|   shouldRepeat: false
 | |
| };
 | |
| var LOCAL_FILES_SETTINGS = {
 | |
|   icon: "folder",
 | |
|   name: "Local Files",
 | |
|   shouldEpisodeRemoveAfterPlay: false,
 | |
|   shouldRepeat: false
 | |
| };
 | |
| var DEFAULT_SETTINGS = {
 | |
|   savedFeeds: {},
 | |
|   podNotes: {},
 | |
|   defaultPlaybackRate: 1,
 | |
|   playedEpisodes: {},
 | |
|   favorites: {
 | |
|     ...FAVORITES_SETTINGS,
 | |
|     episodes: []
 | |
|   },
 | |
|   queue: {
 | |
|     ...QUEUE_SETTINGS,
 | |
|     episodes: []
 | |
|   },
 | |
|   playlists: {},
 | |
|   skipBackwardLength: 15,
 | |
|   skipForwardLength: 15,
 | |
|   currentEpisode: void 0,
 | |
|   timestamp: {
 | |
|     template: "- {{time}} "
 | |
|   },
 | |
|   note: {
 | |
|     path: "",
 | |
|     template: ""
 | |
|   },
 | |
|   download: {
 | |
|     path: ""
 | |
|   },
 | |
|   downloadedEpisodes: {},
 | |
|   localFiles: {
 | |
|     ...LOCAL_FILES_SETTINGS,
 | |
|     episodes: []
 | |
|   },
 | |
|   openAIApiKey: "",
 | |
|   transcript: {
 | |
|     path: "transcripts/{{podcast}}/{{title}}.md",
 | |
|     template: "# {{title}}\n\nPodcast: {{podcast}}\nDate: {{date}}\n\n{{transcript}}"
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/ui/settings/PodNotesSettingsTab.ts
 | |
| var import_obsidian11 = require("obsidian");
 | |
| 
 | |
| // node_modules/tslib/modules/index.js
 | |
| var import_tslib = __toESM(require_tslib(), 1);
 | |
| var {
 | |
|   __extends,
 | |
|   __assign,
 | |
|   __rest,
 | |
|   __decorate,
 | |
|   __param,
 | |
|   __metadata,
 | |
|   __awaiter,
 | |
|   __generator,
 | |
|   __exportStar,
 | |
|   __createBinding,
 | |
|   __values,
 | |
|   __read,
 | |
|   __spread,
 | |
|   __spreadArrays,
 | |
|   __spreadArray,
 | |
|   __await,
 | |
|   __asyncGenerator,
 | |
|   __asyncDelegator,
 | |
|   __asyncValues,
 | |
|   __makeTemplateObject,
 | |
|   __importStar,
 | |
|   __importDefault,
 | |
|   __classPrivateFieldGet,
 | |
|   __classPrivateFieldSet,
 | |
|   __classPrivateFieldIn
 | |
| } = import_tslib.default;
 | |
| 
 | |
| // src/ui/settings/PodcastQueryGrid.svelte
 | |
| var import_obsidian6 = require("obsidian");
 | |
| 
 | |
| // src/iTunesAPIConsumer.ts
 | |
| var import_obsidian2 = require("obsidian");
 | |
| async function queryiTunesPodcasts(query) {
 | |
|   const url = new URL("https://itunes.apple.com/search?");
 | |
|   url.searchParams.append("term", query);
 | |
|   url.searchParams.append("media", "podcast");
 | |
|   url.searchParams.append("limit", "3");
 | |
|   url.searchParams.append("kind", "podcast");
 | |
|   const res = await (0, import_obsidian2.requestUrl)({ url: url.href });
 | |
|   const data = res.json.results;
 | |
|   return data.map((d) => ({
 | |
|     title: d.collectionName,
 | |
|     url: d.feedUrl,
 | |
|     artworkUrl: d.artworkUrl100,
 | |
|     collectionId: d.collectionId
 | |
|   }));
 | |
| }
 | |
| 
 | |
| // src/parser/feedParser.ts
 | |
| var import_obsidian3 = require("obsidian");
 | |
| var FeedParser = class {
 | |
|   constructor(feed) {
 | |
|     this.feed = feed;
 | |
|   }
 | |
|   async findItemByTitle(title, url) {
 | |
|     const body = await this.parseFeed(url);
 | |
|     const items = body.querySelectorAll("item");
 | |
|     const item = Array.from(items).find((item2) => {
 | |
|       const parsed = this.parseItem(item2);
 | |
|       const isMatch = parsed && parsed.title === title;
 | |
|       return isMatch;
 | |
|     });
 | |
|     if (!item) {
 | |
|       throw new Error("Could not find episode");
 | |
|     }
 | |
|     const episode = this.parseItem(item);
 | |
|     const feed = await this.getFeed(url);
 | |
|     if (!episode) {
 | |
|       throw new Error("Episode is invalid.");
 | |
|     }
 | |
|     if (!episode.artworkUrl) {
 | |
|       episode.artworkUrl = feed.artworkUrl;
 | |
|     }
 | |
|     if (!episode.podcastName) {
 | |
|       episode.podcastName = feed.title;
 | |
|     }
 | |
|     if (!episode.feedUrl) {
 | |
|       episode.feedUrl = feed.url;
 | |
|     }
 | |
|     return episode;
 | |
|   }
 | |
|   async getEpisodes(url) {
 | |
|     const body = await this.parseFeed(url);
 | |
|     return this.parsePage(body);
 | |
|   }
 | |
|   async getFeed(url) {
 | |
|     const body = await this.parseFeed(url);
 | |
|     const titleEl = body.querySelector("title");
 | |
|     const linkEl = body.querySelector("link");
 | |
|     const itunesImageEl = body.querySelector("image");
 | |
|     if (!titleEl || !linkEl) {
 | |
|       throw new Error("Invalid RSS feed");
 | |
|     }
 | |
|     const title = titleEl.textContent || "";
 | |
|     const artworkUrl = itunesImageEl?.getAttribute("href") || itunesImageEl?.querySelector("url")?.textContent || "";
 | |
|     return {
 | |
|       title,
 | |
|       url,
 | |
|       artworkUrl
 | |
|     };
 | |
|   }
 | |
|   parsePage(page) {
 | |
|     const items = page.querySelectorAll("item");
 | |
|     function isEpisode(ep) {
 | |
|       return !!ep;
 | |
|     }
 | |
|     return Array.from(items).map(this.parseItem.bind(this)).filter(isEpisode);
 | |
|   }
 | |
|   parseItem(item) {
 | |
|     const titleEl = item.querySelector("title");
 | |
|     const streamUrlEl = item.querySelector("enclosure");
 | |
|     const linkEl = item.querySelector("link");
 | |
|     const descriptionEl = item.querySelector("description");
 | |
|     const contentEl = item.querySelector("*|encoded");
 | |
|     const pubDateEl = item.querySelector("pubDate");
 | |
|     const itunesImageEl = item.querySelector("image");
 | |
|     const itunesTitleEl = item.getElementsByTagName("itunes:title")[0];
 | |
|     if (!titleEl || !streamUrlEl || !pubDateEl) {
 | |
|       return null;
 | |
|     }
 | |
|     const title = titleEl.textContent || "";
 | |
|     const streamUrl = streamUrlEl.getAttribute("url") || "";
 | |
|     const url = linkEl?.textContent || "";
 | |
|     const description = descriptionEl?.textContent || "";
 | |
|     const content = contentEl?.textContent || "";
 | |
|     const pubDate = new Date(pubDateEl.textContent);
 | |
|     const artworkUrl = itunesImageEl?.getAttribute("href") || this.feed?.artworkUrl;
 | |
|     const itunesTitle = itunesTitleEl?.textContent;
 | |
|     return {
 | |
|       title,
 | |
|       streamUrl,
 | |
|       url: url || this.feed?.url || "",
 | |
|       description,
 | |
|       content,
 | |
|       podcastName: this.feed?.title || "",
 | |
|       artworkUrl,
 | |
|       episodeDate: pubDate,
 | |
|       feedUrl: this.feed?.url || "",
 | |
|       itunesTitle: itunesTitle || ""
 | |
|     };
 | |
|   }
 | |
|   async parseFeed(feedUrl) {
 | |
|     const req = await (0, import_obsidian3.requestUrl)({ url: feedUrl });
 | |
|     const dp = new DOMParser();
 | |
|     const body = dp.parseFromString(req.text, "text/xml");
 | |
|     return body;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/utility/checkStringIsUrl.ts
 | |
| function checkStringIsUrl(url) {
 | |
|   try {
 | |
|     return new URL(url);
 | |
|   } catch (e) {
 | |
|     return null;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // src/ui/obsidian/Text.svelte
 | |
| var import_obsidian4 = require("obsidian");
 | |
| 
 | |
| // src/utility/extractStylesFromObj.ts
 | |
| function extractStylesFromObj(obj) {
 | |
|   return Object.entries(obj).map(([key, value]) => `${key}: ${value}`).join("; ");
 | |
| }
 | |
| 
 | |
| // src/ui/obsidian/Text.svelte
 | |
| function create_fragment(ctx) {
 | |
|   let span;
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       ctx[6](span);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       ctx[6](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance($$self, $$props, $$invalidate) {
 | |
|   let { value = "" } = $$props;
 | |
|   let { disabled = false } = $$props;
 | |
|   let { placeholder = "" } = $$props;
 | |
|   let { type = "text" } = $$props;
 | |
|   let textRef;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   let text2;
 | |
|   let { style: styles = {} } = $$props;
 | |
|   onMount(() => {
 | |
|     text2 = new import_obsidian4.TextComponent(textRef);
 | |
|     updateTextComponentAttributes(text2);
 | |
|   });
 | |
|   afterUpdate(() => {
 | |
|     updateTextComponentAttributes(text2);
 | |
|   });
 | |
|   function updateTextComponentAttributes(component) {
 | |
|     if (value !== void 0)
 | |
|       component.setValue(value);
 | |
|     if (disabled)
 | |
|       component.setDisabled(disabled);
 | |
|     if (placeholder)
 | |
|       component.setPlaceholder(placeholder);
 | |
|     if (type)
 | |
|       component.inputEl.type = type;
 | |
|     if (styles) {
 | |
|       text2.inputEl.setAttr("style", extractStylesFromObj(styles));
 | |
|     }
 | |
|     component.onChange((newValue) => {
 | |
|       $$invalidate(1, value = newValue);
 | |
|       dispatch2("change", { value: newValue });
 | |
|     });
 | |
|   }
 | |
|   function span_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       textRef = $$value;
 | |
|       $$invalidate(0, textRef);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("value" in $$props2)
 | |
|       $$invalidate(1, value = $$props2.value);
 | |
|     if ("disabled" in $$props2)
 | |
|       $$invalidate(2, disabled = $$props2.disabled);
 | |
|     if ("placeholder" in $$props2)
 | |
|       $$invalidate(3, placeholder = $$props2.placeholder);
 | |
|     if ("type" in $$props2)
 | |
|       $$invalidate(4, type = $$props2.type);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(5, styles = $$props2.style);
 | |
|   };
 | |
|   return [textRef, value, disabled, placeholder, type, styles, span_binding];
 | |
| }
 | |
| var Text = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance, create_fragment, safe_not_equal, {
 | |
|       value: 1,
 | |
|       disabled: 2,
 | |
|       placeholder: 3,
 | |
|       type: 4,
 | |
|       style: 5
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var Text_default = Text;
 | |
| 
 | |
| // src/ui/obsidian/Button.svelte
 | |
| var import_obsidian5 = require("obsidian");
 | |
| 
 | |
| // src/types/IconType.ts
 | |
| var ICON_LIST_UNIQUE = /* @__PURE__ */ new Set(["activity", "airplay", "alarm-check", "alarm-clock-off", "alarm-clock", "alarm-minus", "alarm-plus", "album", "alert-circle", "alert-octagon", "alert-triangle", "align-center-horizontal", "align-center-vertical", "align-center", "align-end-horizontal", "align-end-vertical", "align-horizontal-distribute-center", "align-horizontal-distribute-end", "align-horizontal-distribute-start", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "align-horizontal-space-around", "align-horizontal-space-between", "align-justify", "align-left", "align-right", "align-start-horizontal", "align-start-vertical", "align-vertical-distribute-center", "align-vertical-distribute-end", "align-vertical-distribute-start", "align-vertical-justify-center", "align-vertical-justify-end", "align-vertical-justify-start", "align-vertical-space-around", "align-vertical-space-between", "anchor", "aperture", "archive", "arrow-big-down", "arrow-big-left", "arrow-big-right", "arrow-big-up", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left-right", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "asterisk", "at-sign", "award", "axe", "banknote", "bar-chart-2", "bar-chart", "baseline", "battery-charging", "battery-full", "battery-low", "battery-medium", "battery", "beaker", "bell-minus", "bell-off", "bell-plus", "bell-ring", "bell", "bike", "binary", "bitcoin", "bluetooth-connected", "bluetooth-off", "bluetooth-searching", "bluetooth", "bold", "book-open", "book", "bookmark-minus", "bookmark-plus", "bookmark", "bot", "box-select", "box", "briefcase", "brush", "bug", "building-2", "building", "bus", "calculator", "calendar", "camera-off", "camera", "car", "carrot", "cast", "check-circle-2", "check-circle", "check-square", "check", "chevron-down", "chevron-first", "chevron-last", "chevron-left", "chevron-right", "chevron-up", "chevrons-down-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up-down", "chevrons-up", "chrome", "circle-slashed", "circle", "clipboard-check", "clipboard-copy", "clipboard-list", "clipboard-x", "clipboard", "clock-1", "clock-10", "clock-11", "clock-12", "clock-2", "clock-3", "clock-4", "clock-5", "clock-6", "clock-7", "clock-8", "clock-9", "clock", "cloud-drizzle", "cloud-fog", "cloud-hail", "cloud-lightning", "cloud-moon", "cloud-off", "cloud-rain-wind", "cloud-rain", "cloud-snow", "cloud-sun", "cloud", "cloudy", "clover", "code-2", "code", "codepen", "codesandbox", "coffee", "coins", "columns", "command", "compass", "contact", "contrast", "cookie", "copy", "copyleft", "copyright", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "cross", "crosshair", "crown", "currency", "database", "delete", "dice-1", "dice-2", "dice-3", "dice-4", "dice-5", "dice-6", "disc", "divide-circle", "divide-square", "divide", "dollar-sign", "download-cloud", "download", "dribbble", "droplet", "droplets", "drumstick", "edit-2", "edit-3", "edit", "egg", "equal-not", "equal", "eraser", "euro", "expand", "external-link", "eye-off", "eye", "facebook", "fast-forward", "feather", "figma", "file-check-2", "file-check", "file-code", "file-digit", "file-input", "file-minus-2", "file-minus", "file-output", "file-plus-2", "file-plus", "file-search", "file-text", "file-x-2", "file-x", "file", "files", "film", "filter", "flag-off", "flag-triangle-left", "flag-triangle-right", "flag", "flame", "flashlight-off", "flashlight", "flask-conical", "flask-round", "folder-minus", "folder-open", "folder-plus", "folder", "form-input", "forward", "frame", "framer", "frown", "function-square", "gamepad-2", "gamepad", "gauge", "gavel", "gem", "ghost", "gift", "git-branch-plus", "git-branch", "git-commit", "git-fork", "git-merge", "git-pull-request", "github", "gitlab", "glasses", "globe-2", "globe", "grab", "graduation-cap", "grid", "grip-horizontal", "grip-vertical", "hammer", "hand-metal", "hand", "hard-drive", "hard-hat", "hash", "haze", "headphones", "heart", "help-circle", "hexagon", "highlighter", "history", "home", "image-minus", "image-off", "image-plus", "image", "import", "inbox", "indent", "indian-rupee", "infinity", "info", "inspect", "instagram", "italic", "japanese-yen", "key", "keyboard", "landmark", "languages", "laptop-2", "laptop", "lasso-select", "lasso", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-template", "layout", "library", "life-buoy", "lightbulb-off", "lightbulb", "link-2-off", "link-2", "link", "linkedin", "list-checks", "list-minus", "list-ordered", "list-plus", "list-x", "list", "loader-2", "loader", "locate-fixed", "locate-off", "locate", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "megaphone", "meh", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor-off", "monitor-speaker", "monitor", "moon", "more-horizontal", "more-vertical", "mountain-snow", "mountain", "mouse-pointer-2", "mouse-pointer-click", "mouse-pointer", "mouse", "move-diagonal-2", "move-diagonal", "move-horizontal", "move-vertical", "move", "music", "navigation-2", "navigation", "network", "octagon", "option", "outdent", "package-check", "package-minus", "package-plus", "package-search", "package-x", "package", "palette", "palmtree", "paperclip", "pause-circle", "pause-octagon", "pause", "pen-tool", "pencil", "percent", "person-standing", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "piggy-bank", "pin", "pipette", "plane", "play-circle", "play", "plug-zap", "plus-circle", "plus-square", "plus", "pocket", "podcast", "pointer", "pound-sterling", "power-off", "power", "printer", "qr-code", "quote", "radio-receiver", "radio", "redo", "refresh-ccw", "refresh-cw", "regex", "repeat-1", "repeat", "reply-all", "reply", "rewind", "rocket", "rocking-chair", "rotate-ccw", "rotate-cw", "rss", "ruler", "russian-ruble", "save", "scale", "scan-line", "scan", "scissors", "screen-share-off", "screen-share", "search", "send", "separator-horizontal", "separator-vertical", "server-crash", "server-off", "server", "settings-2", "settings", "share-2", "share", "sheet", "shield-alert", "shield-check", "shield-close", "shield-off", "shield", "shirt", "shopping-bag", "shopping-cart", "shovel", "shrink", "shuffle", "sidebar-close", "sidebar-open", "sidebar", "sigma", "signal-high", "signal-low", "signal-medium", "signal-zero", "signal", "skip-back", "skip-forward", "skull", "slack", "slash", "sliders", "smartphone-charging", "smartphone", "smile", "snowflake", "sort-asc", "sort-desc", "speaker", "sprout", "square", "star-half", "star", "stop-circle", "stretch-horizontal", "stretch-vertical", "strikethrough", "subscript", "sun", "sunrise", "sunset", "superscript", "swiss-franc", "switch-camera", "table", "tablet", "tag", "target", "tent", "terminal-square", "terminal", "text-cursor-input", "text-cursor", "thermometer-snowflake", "thermometer-sun", "thermometer", "thumbs-down", "thumbs-up", "ticket", "timer-off", "timer-reset", "timer", "toggle-left", "toggle-right", "tornado", "trash-2", "trash", "trello", "trending-down", "trending-up", "triangle", "truck", "tv-2", "tv", "twitch", "twitter", "type", "umbrella", "underline", "undo", "unlink-2", "unlink", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "verified", "vibrate", "video-off", "video", "view", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "wallet", "wand", "watch", "waves", "webcam", "wifi-off", "wifi", "wind", "wrap-text", "wrench", "x-circle", "x-octagon", "x-square", "x", "youtube", "zap-off", "zap", "zoom-in", "zoom-out", "search-large", "search", "activity", "airplay", "alarm-check", "alarm-clock-off", "alarm-clock", "alarm-minus", "alarm-plus", "album", "alert-circle", "alert-octagon", "alert-triangle", "align-center-horizontal", "align-center-vertical", "align-center", "align-end-horizontal", "align-end-vertical", "align-horizontal-distribute-center", "align-horizontal-distribute-end", "align-horizontal-distribute-start", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "align-horizontal-space-around", "align-horizontal-space-between", "align-justify", "align-left", "align-right", "align-start-horizontal", "align-start-vertical", "align-vertical-distribute-center", "align-vertical-distribute-end", "align-vertical-distribute-start", "align-vertical-justify-center", "align-vertical-justify-end", "align-vertical-justify-start", "align-vertical-space-around", "align-vertical-space-between", "anchor", "aperture", "archive", "arrow-big-down", "arrow-big-left", "arrow-big-right", "arrow-big-up", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left-right", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "asterisk", "at-sign", "award", "axe", "banknote", "bar-chart-2", "bar-chart", "baseline", "battery-charging", "battery-full", "battery-low", "battery-medium", "battery", "beaker", "bell-minus", "bell-off", "bell-plus", "bell-ring", "bell", "bike", "binary", "bitcoin", "bluetooth-connected", "bluetooth-off", "bluetooth-searching", "bluetooth", "bold", "book-open", "book", "bookmark-minus", "bookmark-plus", "bookmark", "bot", "box-select", "box", "briefcase", "brush", "bug", "building-2", "building", "bus", "calculator", "calendar", "camera-off", "camera", "car", "carrot", "cast", "check-circle-2", "check-circle", "check-square", "check", "chevron-down", "chevron-first", "chevron-last", "chevron-left", "chevron-right", "chevron-up", "chevrons-down-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up-down", "chevrons-up", "chrome", "circle-slashed", "circle", "clipboard-check", "clipboard-copy", "clipboard-list", "clipboard-x", "clipboard", "clock-1", "clock-10", "clock-11", "clock-12", "clock-2", "clock-3", "clock-4", "clock-5", "clock-6", "clock-7", "clock-8", "clock-9", "lucide-clock", "cloud-drizzle", "cloud-fog", "cloud-hail", "cloud-lightning", "cloud-moon", "cloud-off", "cloud-rain-wind", "cloud-rain", "cloud-snow", "cloud-sun", "lucide-cloud", "cloudy", "clover", "code-2", "code", "codepen", "codesandbox", "coffee", "coins", "columns", "command", "compass", "contact", "contrast", "cookie", "copy", "copyleft", "copyright", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "lucide-cross", "crosshair", "crown", "currency", "database", "delete", "dice-1", "dice-2", "dice-3", "dice-4", "dice-5", "dice-6", "disc", "divide-circle", "divide-square", "divide", "dollar-sign", "download-cloud", "download", "dribbble", "droplet", "droplets", "drumstick", "edit-2", "edit-3", "edit", "egg", "equal-not", "equal", "eraser", "euro", "expand", "external-link", "eye-off", "eye", "facebook", "fast-forward", "feather", "figma", "file-check-2", "file-check", "file-code", "file-digit", "file-input", "file-minus-2", "file-minus", "file-output", "file-plus-2", "file-plus", "file-search", "file-text", "file-x-2", "file-x", "file", "files", "film", "filter", "flag-off", "flag-triangle-left", "flag-triangle-right", "flag", "flame", "flashlight-off", "flashlight", "flask-conical", "flask-round", "folder-minus", "folder-open", "folder-plus", "lucide-folder", "form-input", "forward", "frame", "framer", "frown", "function-square", "gamepad-2", "gamepad", "gauge", "gavel", "gem", "ghost", "gift", "git-branch-plus", "git-branch", "git-commit", "git-fork", "git-merge", "git-pull-request", "github", "gitlab", "glasses", "globe-2", "globe", "grab", "graduation-cap", "grid", "grip-horizontal", "grip-vertical", "hammer", "hand-metal", "hand", "hard-drive", "hard-hat", "hash", "haze", "headphones", "heart", "help-circle", "hexagon", "highlighter", "history", "home", "image-minus", "image-off", "image-plus", "image", "import", "inbox", "indent", "indian-rupee", "infinity", "lucide-info", "inspect", "instagram", "italic", "japanese-yen", "key", "keyboard", "landmark", "lucide-languages", "laptop-2", "laptop", "lasso-select", "lasso", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-template", "layout", "library", "life-buoy", "lightbulb-off", "lightbulb", "link-2-off", "link-2", "lucide-link", "linkedin", "list-checks", "list-minus", "list-ordered", "list-plus", "list-x", "list", "loader-2", "loader", "locate-fixed", "locate-off", "locate", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "megaphone", "meh", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor-off", "monitor-speaker", "monitor", "moon", "more-horizontal", "more-vertical", "mountain-snow", "mountain", "mouse-pointer-2", "mouse-pointer-click", "mouse-pointer", "mouse", "move-diagonal-2", "move-diagonal", "move-horizontal", "move-vertical", "move", "music", "navigation-2", "navigation", "network", "octagon", "option", "outdent", "package-check", "package-minus", "package-plus", "package-search", "package-x", "package", "palette", "palmtree", "paperclip", "pause-circle", "pause-octagon", "pause", "pen-tool", "lucide-pencil", "percent", "person-standing", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "piggy-bank", "lucide-pin", "pipette", "plane", "play-circle", "play", "plug-zap", "plus-circle", "plus-square", "plus", "pocket", "podcast", "pointer", "pound-sterling", "power-off", "power", "printer", "qr-code", "quote", "radio-receiver", "radio", "redo", "refresh-ccw", "refresh-cw", "regex", "repeat-1", "repeat", "reply-all", "reply", "rewind", "rocket", "rocking-chair", "rotate-ccw", "rotate-cw", "rss", "ruler", "russian-ruble", "save", "scale", "scan-line", "scan", "scissors", "screen-share-off", "screen-share", "lucide-search", "send", "separator-horizontal", "separator-vertical", "server-crash", "server-off", "server", "settings-2", "settings", "share-2", "share", "sheet", "shield-alert", "shield-check", "shield-close", "shield-off", "shield", "shirt", "shopping-bag", "shopping-cart", "shovel", "shrink", "shuffle", "sidebar-close", "sidebar-open", "sidebar", "sigma", "signal-high", "signal-low", "signal-medium", "signal-zero", "signal", "skip-back", "skip-forward", "skull", "slack", "slash", "sliders", "smartphone-charging", "smartphone", "smile", "snowflake", "sort-asc", "sort-desc", "speaker", "sprout", "square", "star-half", "lucide-star", "stop-circle", "stretch-horizontal", "stretch-vertical", "strikethrough", "subscript", "sun", "sunrise", "sunset", "superscript", "swiss-franc", "switch-camera", "table", "tablet", "tag", "target", "tent", "terminal-square", "terminal", "text-cursor-input", "text-cursor", "thermometer-snowflake", "thermometer-sun", "thermometer", "thumbs-down", "thumbs-up", "ticket", "timer-off", "timer-reset", "timer", "toggle-left", "toggle-right", "tornado", "trash-2", "lucide-trash", "trello", "trending-down", "trending-up", "triangle", "truck", "tv-2", "tv", "twitch", "twitter", "type", "umbrella", "underline", "undo", "unlink-2", "unlink", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "verified", "vibrate", "video-off", "video", "view", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "wallet", "wand", "watch", "waves", "webcam", "wifi-off", "wifi", "wind", "wrap-text", "wrench", "x-circle", "x-octagon", "x-square", "x", "youtube", "zap-off", "zap", "zoom-in", "zoom-out", "search-large", "lucide-search"]);
 | |
| var ICON_LIST = Array.from(ICON_LIST_UNIQUE);
 | |
| 
 | |
| // src/ui/obsidian/Button.svelte
 | |
| function create_fragment2(ctx) {
 | |
|   let span;
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       ctx[9](span);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       ctx[9](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance2($$self, $$props, $$invalidate) {
 | |
|   let { text: text2 = "" } = $$props;
 | |
|   let { tooltip = "" } = $$props;
 | |
|   let { icon = void 0 } = $$props;
 | |
|   let { disabled = false } = $$props;
 | |
|   let { warning = false } = $$props;
 | |
|   let { cta = false } = $$props;
 | |
|   let buttonRef;
 | |
|   let { class: className } = $$props;
 | |
|   let { style: styles } = $$props;
 | |
|   let button;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   onMount(() => createButton(buttonRef));
 | |
|   afterUpdate(() => updateButtonAttributes(button));
 | |
|   function createButton(container) {
 | |
|     button = new import_obsidian5.ButtonComponent(container);
 | |
|     updateButtonAttributes(button);
 | |
|   }
 | |
|   function updateButtonAttributes(btn) {
 | |
|     if (text2)
 | |
|       btn.setButtonText(text2);
 | |
|     if (tooltip)
 | |
|       btn.setTooltip(tooltip);
 | |
|     if (icon)
 | |
|       btn.setIcon(icon);
 | |
|     if (disabled)
 | |
|       btn.setDisabled(disabled);
 | |
|     if (warning)
 | |
|       btn.setWarning();
 | |
|     else
 | |
|       btn.buttonEl.classList.remove("mod-warning");
 | |
|     if (className)
 | |
|       btn.setClass(className);
 | |
|     if (cta)
 | |
|       btn.setCta();
 | |
|     else
 | |
|       btn.removeCta();
 | |
|     btn.onClick((event) => {
 | |
|       dispatch2("click", { event });
 | |
|     });
 | |
|     if (styles) {
 | |
|       btn.buttonEl.setAttr("style", extractStylesFromObj(styles));
 | |
|     }
 | |
|   }
 | |
|   function span_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       buttonRef = $$value;
 | |
|       $$invalidate(0, buttonRef);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("text" in $$props2)
 | |
|       $$invalidate(1, text2 = $$props2.text);
 | |
|     if ("tooltip" in $$props2)
 | |
|       $$invalidate(2, tooltip = $$props2.tooltip);
 | |
|     if ("icon" in $$props2)
 | |
|       $$invalidate(3, icon = $$props2.icon);
 | |
|     if ("disabled" in $$props2)
 | |
|       $$invalidate(4, disabled = $$props2.disabled);
 | |
|     if ("warning" in $$props2)
 | |
|       $$invalidate(5, warning = $$props2.warning);
 | |
|     if ("cta" in $$props2)
 | |
|       $$invalidate(6, cta = $$props2.cta);
 | |
|     if ("class" in $$props2)
 | |
|       $$invalidate(7, className = $$props2.class);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(8, styles = $$props2.style);
 | |
|   };
 | |
|   return [
 | |
|     buttonRef,
 | |
|     text2,
 | |
|     tooltip,
 | |
|     icon,
 | |
|     disabled,
 | |
|     warning,
 | |
|     cta,
 | |
|     className,
 | |
|     styles,
 | |
|     span_binding
 | |
|   ];
 | |
| }
 | |
| var Button = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance2, create_fragment2, safe_not_equal, {
 | |
|       text: 1,
 | |
|       tooltip: 2,
 | |
|       icon: 3,
 | |
|       disabled: 4,
 | |
|       warning: 5,
 | |
|       cta: 6,
 | |
|       class: 7,
 | |
|       style: 8
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var Button_default = Button;
 | |
| 
 | |
| // node_modules/svelte/transition/index.mjs
 | |
| function fade(node, { delay = 0, duration: duration2 = 400, easing = identity } = {}) {
 | |
|   const o = +getComputedStyle(node).opacity;
 | |
|   return {
 | |
|     delay,
 | |
|     duration: duration2,
 | |
|     easing,
 | |
|     css: (t) => `opacity: ${t * o}`
 | |
|   };
 | |
| }
 | |
| 
 | |
| // src/ui/settings/PodcastResultCard.svelte
 | |
| function add_css(target) {
 | |
|   append_styles(target, "svelte-1yveck6", ".podcast-result-card.svelte-1yveck6{display:flex;align-items:center;padding:16px;border:1px solid var(--background-modifier-border);border-radius:8px;background-color:var(--background-secondary);max-width:100%;transition:all 0.3s ease;position:relative}.podcast-artwork-container.svelte-1yveck6{width:70px;height:70px;flex-shrink:0;margin-right:20px;overflow:hidden;border-radius:4px;position:relative}.podcast-artwork.svelte-1yveck6{width:100%;height:100%;object-fit:cover;position:absolute;top:0;left:0}.podcast-result-card.svelte-1yveck6:hover{box-shadow:0 2px 8px rgba(0, 0, 0, 0.1);transform:translateY(-2px)}.podcast-info.svelte-1yveck6{flex-grow:1;min-width:0;padding-right:12px}.podcast-title.svelte-1yveck6{margin:0 0 6px 0;font-size:16px;font-weight:bold;line-height:1.3;word-break:break-word}.podcast-actions.svelte-1yveck6{display:flex;align-items:center;flex-shrink:0}.podcast-actions button{padding:4px;width:24px;height:24px}.podcast-actions button svg{width:16px;height:16px}");
 | |
| }
 | |
| function create_else_block(ctx) {
 | |
|   let button;
 | |
|   let current;
 | |
|   button = new Button_default({
 | |
|     props: {
 | |
|       icon: "plus",
 | |
|       "aria-label": `Add ${ctx[0].title} podcast`
 | |
|     }
 | |
|   });
 | |
|   button.$on("click", ctx[4]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(button.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(button, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const button_changes = {};
 | |
|       if (dirty & 1)
 | |
|         button_changes["aria-label"] = `Add ${ctx2[0].title} podcast`;
 | |
|       button.$set(button_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(button.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(button.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(button, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block(ctx) {
 | |
|   let button;
 | |
|   let current;
 | |
|   button = new Button_default({
 | |
|     props: {
 | |
|       icon: "trash",
 | |
|       "aria-label": `Remove ${ctx[0].title} podcast`
 | |
|     }
 | |
|   });
 | |
|   button.$on("click", ctx[3]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(button.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(button, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const button_changes = {};
 | |
|       if (dirty & 1)
 | |
|         button_changes["aria-label"] = `Remove ${ctx2[0].title} podcast`;
 | |
|       button.$set(button_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(button.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(button.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(button, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment3(ctx) {
 | |
|   let div3;
 | |
|   let div0;
 | |
|   let img;
 | |
|   let img_src_value;
 | |
|   let img_alt_value;
 | |
|   let t0;
 | |
|   let div1;
 | |
|   let h3;
 | |
|   let t1_value = ctx[0].title + "";
 | |
|   let t1;
 | |
|   let t2;
 | |
|   let div2;
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let div3_transition;
 | |
|   let current;
 | |
|   const if_block_creators = [create_if_block, create_else_block];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[1])
 | |
|       return 0;
 | |
|     return 1;
 | |
|   }
 | |
|   current_block_type_index = select_block_type(ctx, -1);
 | |
|   if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       div3 = element("div");
 | |
|       div0 = element("div");
 | |
|       img = element("img");
 | |
|       t0 = space();
 | |
|       div1 = element("div");
 | |
|       h3 = element("h3");
 | |
|       t1 = text(t1_value);
 | |
|       t2 = space();
 | |
|       div2 = element("div");
 | |
|       if_block.c();
 | |
|       if (!src_url_equal(img.src, img_src_value = ctx[0].artworkUrl))
 | |
|         attr(img, "src", img_src_value);
 | |
|       attr(img, "alt", img_alt_value = `Artwork for ${ctx[0].title}`);
 | |
|       attr(img, "class", "podcast-artwork svelte-1yveck6");
 | |
|       attr(div0, "class", "podcast-artwork-container svelte-1yveck6");
 | |
|       attr(h3, "class", "podcast-title svelte-1yveck6");
 | |
|       attr(div1, "class", "podcast-info svelte-1yveck6");
 | |
|       attr(div2, "class", "podcast-actions svelte-1yveck6");
 | |
|       attr(div3, "class", "podcast-result-card svelte-1yveck6");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div3, anchor);
 | |
|       append(div3, div0);
 | |
|       append(div0, img);
 | |
|       append(div3, t0);
 | |
|       append(div3, div1);
 | |
|       append(div1, h3);
 | |
|       append(h3, t1);
 | |
|       append(div3, t2);
 | |
|       append(div3, div2);
 | |
|       if_blocks[current_block_type_index].m(div2, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (!current || dirty & 1 && !src_url_equal(img.src, img_src_value = ctx2[0].artworkUrl)) {
 | |
|         attr(img, "src", img_src_value);
 | |
|       }
 | |
|       if (!current || dirty & 1 && img_alt_value !== (img_alt_value = `Artwork for ${ctx2[0].title}`)) {
 | |
|         attr(img, "alt", img_alt_value);
 | |
|       }
 | |
|       if ((!current || dirty & 1) && t1_value !== (t1_value = ctx2[0].title + ""))
 | |
|         set_data(t1, t1_value);
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|       } else {
 | |
|         group_outros();
 | |
|         transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|           if_blocks[previous_block_index] = null;
 | |
|         });
 | |
|         check_outros();
 | |
|         if_block = if_blocks[current_block_type_index];
 | |
|         if (!if_block) {
 | |
|           if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|           if_block.c();
 | |
|         } else {
 | |
|           if_block.p(ctx2, dirty);
 | |
|         }
 | |
|         transition_in(if_block, 1);
 | |
|         if_block.m(div2, null);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       add_render_callback(() => {
 | |
|         if (!div3_transition)
 | |
|           div3_transition = create_bidirectional_transition(div3, fade, { duration: 300 }, true);
 | |
|         div3_transition.run(1);
 | |
|       });
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       if (!div3_transition)
 | |
|         div3_transition = create_bidirectional_transition(div3, fade, { duration: 300 }, false);
 | |
|       div3_transition.run(0);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div3);
 | |
|       if_blocks[current_block_type_index].d();
 | |
|       if (detaching && div3_transition)
 | |
|         div3_transition.end();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance3($$self, $$props, $$invalidate) {
 | |
|   let { podcast } = $$props;
 | |
|   let { isSaved = false } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   const click_handler = () => dispatch2("removePodcast", { podcast });
 | |
|   const click_handler_1 = () => dispatch2("addPodcast", { podcast });
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("podcast" in $$props2)
 | |
|       $$invalidate(0, podcast = $$props2.podcast);
 | |
|     if ("isSaved" in $$props2)
 | |
|       $$invalidate(1, isSaved = $$props2.isSaved);
 | |
|   };
 | |
|   return [podcast, isSaved, dispatch2, click_handler, click_handler_1];
 | |
| }
 | |
| var PodcastResultCard = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance3, create_fragment3, safe_not_equal, { podcast: 0, isSaved: 1 }, add_css);
 | |
|   }
 | |
| };
 | |
| var PodcastResultCard_default = PodcastResultCard;
 | |
| 
 | |
| // src/ui/settings/PodcastQueryGrid.svelte
 | |
| function add_css2(target) {
 | |
|   append_styles(target, "svelte-nkazu8", ".podcast-query-container.svelte-nkazu8{margin-bottom:2rem}.podcast-query-results.svelte-nkazu8{display:grid;grid-gap:16px;grid-template-columns:repeat(auto-fill, minmax(280px, 1fr))}@media(max-width: 600px){.podcast-query-results.svelte-nkazu8{grid-template-columns:1fr}}");
 | |
| }
 | |
| function get_each_context(ctx, list, i) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   child_ctx[11] = list[i];
 | |
|   return child_ctx;
 | |
| }
 | |
| function create_each_block(key_1, ctx) {
 | |
|   let div;
 | |
|   let podcastresultcard;
 | |
|   let t;
 | |
|   let current;
 | |
|   podcastresultcard = new PodcastResultCard_default({
 | |
|     props: {
 | |
|       podcast: ctx[11],
 | |
|       isSaved: typeof ctx[11].url === "string" && ctx[1][ctx[11].title]?.url === ctx[11].url
 | |
|     }
 | |
|   });
 | |
|   podcastresultcard.$on("addPodcast", ctx[4]);
 | |
|   podcastresultcard.$on("removePodcast", ctx[5]);
 | |
|   return {
 | |
|     key: key_1,
 | |
|     first: null,
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(podcastresultcard.$$.fragment);
 | |
|       t = space();
 | |
|       attr(div, "role", "listitem");
 | |
|       this.first = div;
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(podcastresultcard, div, null);
 | |
|       append(div, t);
 | |
|       current = true;
 | |
|     },
 | |
|     p(new_ctx, dirty) {
 | |
|       ctx = new_ctx;
 | |
|       const podcastresultcard_changes = {};
 | |
|       if (dirty & 1)
 | |
|         podcastresultcard_changes.podcast = ctx[11];
 | |
|       if (dirty & 3)
 | |
|         podcastresultcard_changes.isSaved = typeof ctx[11].url === "string" && ctx[1][ctx[11].title]?.url === ctx[11].url;
 | |
|       podcastresultcard.$set(podcastresultcard_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(podcastresultcard.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(podcastresultcard.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(podcastresultcard);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment4(ctx) {
 | |
|   let div1;
 | |
|   let text_1;
 | |
|   let updating_el;
 | |
|   let t;
 | |
|   let div0;
 | |
|   let each_blocks = [];
 | |
|   let each_1_lookup = /* @__PURE__ */ new Map();
 | |
|   let div1_transition;
 | |
|   let current;
 | |
|   function text_1_el_binding(value) {
 | |
|     ctx[8](value);
 | |
|   }
 | |
|   let text_1_props = {
 | |
|     placeholder: "Search or enter feed URL...",
 | |
|     style: { width: "100%", "margin-bottom": "1rem" }
 | |
|   };
 | |
|   if (ctx[2] !== void 0) {
 | |
|     text_1_props.el = ctx[2];
 | |
|   }
 | |
|   text_1 = new Text_default({ props: text_1_props });
 | |
|   binding_callbacks.push(() => bind(text_1, "el", text_1_el_binding));
 | |
|   text_1.$on("change", ctx[3]);
 | |
|   let each_value = ctx[0];
 | |
|   const get_key = (ctx2) => ctx2[11].url;
 | |
|   for (let i = 0; i < each_value.length; i += 1) {
 | |
|     let child_ctx = get_each_context(ctx, each_value, i);
 | |
|     let key = get_key(child_ctx);
 | |
|     each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));
 | |
|   }
 | |
|   return {
 | |
|     c() {
 | |
|       div1 = element("div");
 | |
|       create_component(text_1.$$.fragment);
 | |
|       t = space();
 | |
|       div0 = element("div");
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].c();
 | |
|       }
 | |
|       attr(div0, "class", "podcast-query-results svelte-nkazu8");
 | |
|       attr(div0, "role", "list");
 | |
|       attr(div0, "aria-label", "Podcast search results");
 | |
|       attr(div1, "class", "podcast-query-container svelte-nkazu8");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div1, anchor);
 | |
|       mount_component(text_1, div1, null);
 | |
|       append(div1, t);
 | |
|       append(div1, div0);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].m(div0, null);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const text_1_changes = {};
 | |
|       if (!updating_el && dirty & 4) {
 | |
|         updating_el = true;
 | |
|         text_1_changes.el = ctx2[2];
 | |
|         add_flush_callback(() => updating_el = false);
 | |
|       }
 | |
|       text_1.$set(text_1_changes);
 | |
|       if (dirty & 51) {
 | |
|         each_value = ctx2[0];
 | |
|         group_outros();
 | |
|         each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx2, each_value, each_1_lookup, div0, outro_and_destroy_block, create_each_block, null, get_each_context);
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(text_1.$$.fragment, local);
 | |
|       for (let i = 0; i < each_value.length; i += 1) {
 | |
|         transition_in(each_blocks[i]);
 | |
|       }
 | |
|       add_render_callback(() => {
 | |
|         if (!div1_transition)
 | |
|           div1_transition = create_bidirectional_transition(div1, fade, { duration: 300 }, true);
 | |
|         div1_transition.run(1);
 | |
|       });
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(text_1.$$.fragment, local);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         transition_out(each_blocks[i]);
 | |
|       }
 | |
|       if (!div1_transition)
 | |
|         div1_transition = create_bidirectional_transition(div1, fade, { duration: 300 }, false);
 | |
|       div1_transition.run(0);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div1);
 | |
|       destroy_component(text_1);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].d();
 | |
|       }
 | |
|       if (detaching && div1_transition)
 | |
|         div1_transition.end();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance4($$self, $$props, $$invalidate) {
 | |
|   let $savedFeeds;
 | |
|   let $podcastsUpdated;
 | |
|   component_subscribe($$self, savedFeeds, ($$value) => $$invalidate(1, $savedFeeds = $$value));
 | |
|   component_subscribe($$self, podcastsUpdated, ($$value) => $$invalidate(7, $podcastsUpdated = $$value));
 | |
|   let searchResults = [];
 | |
|   let gridSizeClass = "grid-3";
 | |
|   let searchQuery = "";
 | |
|   let searchInput;
 | |
|   onMount(() => {
 | |
|     updateSearchResults();
 | |
|     if (searchInput) {
 | |
|       searchInput.focus();
 | |
|     }
 | |
|   });
 | |
|   function updateSearchResults() {
 | |
|     if (searchQuery.trim() === "") {
 | |
|       $$invalidate(0, searchResults = Object.values($savedFeeds));
 | |
|     }
 | |
|   }
 | |
|   const debouncedUpdate = (0, import_obsidian6.debounce)(({ detail: { value } }) => __awaiter(void 0, void 0, void 0, function* () {
 | |
|     $$invalidate(6, searchQuery = value);
 | |
|     const customFeedUrl = checkStringIsUrl(value);
 | |
|     if (customFeedUrl) {
 | |
|       const feed = yield new FeedParser().getFeed(customFeedUrl.href);
 | |
|       $$invalidate(0, searchResults = [feed]);
 | |
|     } else if (value.trim() === "") {
 | |
|       updateSearchResults();
 | |
|     } else {
 | |
|       $$invalidate(0, searchResults = yield queryiTunesPodcasts(value));
 | |
|     }
 | |
|   }), 300, true);
 | |
|   function addPodcast(event) {
 | |
|     const { podcast } = event.detail;
 | |
|     savedFeeds.update((feeds) => Object.assign(Object.assign({}, feeds), { [podcast.title]: podcast }));
 | |
|     updateSearchResults();
 | |
|   }
 | |
|   function removePodcast(event) {
 | |
|     const { podcast } = event.detail;
 | |
|     savedFeeds.update((feeds) => {
 | |
|       const newFeeds = Object.assign({}, feeds);
 | |
|       delete newFeeds[podcast.title];
 | |
|       return newFeeds;
 | |
|     });
 | |
|     updateSearchResults();
 | |
|   }
 | |
|   function text_1_el_binding(value) {
 | |
|     searchInput = value;
 | |
|     $$invalidate(2, searchInput);
 | |
|   }
 | |
|   $$self.$$.update = () => {
 | |
|     if ($$self.$$.dirty & 194) {
 | |
|       $: {
 | |
|         if (searchQuery.trim() === "") {
 | |
|           $$invalidate(0, searchResults = Object.values($savedFeeds));
 | |
|         }
 | |
|         $podcastsUpdated;
 | |
|       }
 | |
|     }
 | |
|     if ($$self.$$.dirty & 1) {
 | |
|       $: {
 | |
|         if (searchResults.length % 3 === 0 || searchResults.length > 3) {
 | |
|           gridSizeClass = "grid-3";
 | |
|         } else if (searchResults.length % 2 === 0) {
 | |
|           gridSizeClass = "grid-2";
 | |
|         } else if (searchResults.length % 1 === 0) {
 | |
|           gridSizeClass = "grid-1";
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   };
 | |
|   return [
 | |
|     searchResults,
 | |
|     $savedFeeds,
 | |
|     searchInput,
 | |
|     debouncedUpdate,
 | |
|     addPodcast,
 | |
|     removePodcast,
 | |
|     searchQuery,
 | |
|     $podcastsUpdated,
 | |
|     text_1_el_binding
 | |
|   ];
 | |
| }
 | |
| var PodcastQueryGrid = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance4, create_fragment4, safe_not_equal, {}, add_css2);
 | |
|   }
 | |
| };
 | |
| var PodcastQueryGrid_default = PodcastQueryGrid;
 | |
| 
 | |
| // src/ui/obsidian/Icon.svelte
 | |
| var import_obsidian7 = require("obsidian");
 | |
| function add_css3(target) {
 | |
|   append_styles(target, "svelte-c77uvx", ".icon-clickable.svelte-c77uvx{cursor:pointer}");
 | |
| }
 | |
| function create_fragment5(ctx) {
 | |
|   let div;
 | |
|   let span;
 | |
|   let div_class_value;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       span = element("span");
 | |
|       attr(div, "class", div_class_value = null_to_empty(ctx[0] ? "icon-clickable" : "") + " svelte-c77uvx");
 | |
|       attr(div, "aria-label", ctx[1]);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       append(div, span);
 | |
|       ctx[7](span);
 | |
|       if (!mounted) {
 | |
|         dispose = listen(div, "click", ctx[3]);
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (dirty & 1 && div_class_value !== (div_class_value = null_to_empty(ctx2[0] ? "icon-clickable" : "") + " svelte-c77uvx")) {
 | |
|         attr(div, "class", div_class_value);
 | |
|       }
 | |
|       if (dirty & 2) {
 | |
|         attr(div, "aria-label", ctx2[1]);
 | |
|       }
 | |
|     },
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       ctx[7](null);
 | |
|       mounted = false;
 | |
|       dispose();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance5($$self, $$props, $$invalidate) {
 | |
|   let { size = 16 } = $$props;
 | |
|   let { icon } = $$props;
 | |
|   let { clickable = true } = $$props;
 | |
|   let { label = "" } = $$props;
 | |
|   let ref;
 | |
|   let { style: styles = {} } = $$props;
 | |
|   let stylesStr;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   onMount(() => {
 | |
|     (0, import_obsidian7.setIcon)(ref, icon, size);
 | |
|     $$invalidate(2, ref.style.cssText = stylesStr, ref);
 | |
|   });
 | |
|   afterUpdate(() => {
 | |
|     (0, import_obsidian7.setIcon)(ref, icon, size);
 | |
|     $$invalidate(2, ref.style.cssText = stylesStr, ref);
 | |
|   });
 | |
|   function forwardClick(event) {
 | |
|     dispatch2("click", { event });
 | |
|   }
 | |
|   function span_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       ref = $$value;
 | |
|       $$invalidate(2, ref);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("size" in $$props2)
 | |
|       $$invalidate(4, size = $$props2.size);
 | |
|     if ("icon" in $$props2)
 | |
|       $$invalidate(5, icon = $$props2.icon);
 | |
|     if ("clickable" in $$props2)
 | |
|       $$invalidate(0, clickable = $$props2.clickable);
 | |
|     if ("label" in $$props2)
 | |
|       $$invalidate(1, label = $$props2.label);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(6, styles = $$props2.style);
 | |
|   };
 | |
|   $$self.$$.update = () => {
 | |
|     if ($$self.$$.dirty & 64) {
 | |
|       $:
 | |
|         stylesStr = extractStylesFromObj(styles);
 | |
|     }
 | |
|   };
 | |
|   return [clickable, label, ref, forwardClick, size, icon, styles, span_binding];
 | |
| }
 | |
| var Icon = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance5, create_fragment5, safe_not_equal, {
 | |
|       size: 4,
 | |
|       icon: 5,
 | |
|       clickable: 0,
 | |
|       label: 1,
 | |
|       style: 6
 | |
|     }, add_css3);
 | |
|   }
 | |
| };
 | |
| var Icon_default = Icon;
 | |
| 
 | |
| // src/ui/settings/PlaylistItem.svelte
 | |
| function add_css4(target) {
 | |
|   append_styles(target, "svelte-nlujum", ".playlist-item.svelte-nlujum{display:flex;align-items:center;justify-content:space-between;padding:0.5rem;border-bottom:1px solid var(--background-modifier-border);width:100%}.playlist-item-left.svelte-nlujum{display:flex;align-items:center}.playlist-item-controls.svelte-nlujum{display:flex;align-items:center;gap:0.25rem}");
 | |
| }
 | |
| function create_if_block2(ctx) {
 | |
|   let icon;
 | |
|   let current;
 | |
|   icon = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[2] ? "check" : "trash",
 | |
|       label: ctx[2] ? "Confirm deletion" : "Delete playlist",
 | |
|       size: 20,
 | |
|       style: { color: "red" }
 | |
|     }
 | |
|   });
 | |
|   icon.$on("click", ctx[3]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(icon.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(icon, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const icon_changes = {};
 | |
|       if (dirty & 4)
 | |
|         icon_changes.icon = ctx2[2] ? "check" : "trash";
 | |
|       if (dirty & 4)
 | |
|         icon_changes.label = ctx2[2] ? "Confirm deletion" : "Delete playlist";
 | |
|       icon.$set(icon_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(icon, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment6(ctx) {
 | |
|   let div2;
 | |
|   let div0;
 | |
|   let icon;
 | |
|   let t0;
 | |
|   let span;
 | |
|   let t1_value = ctx[0].name + "";
 | |
|   let t1;
 | |
|   let t2;
 | |
|   let t3_value = ctx[0].episodes.length + "";
 | |
|   let t3;
 | |
|   let t4;
 | |
|   let t5;
 | |
|   let div1;
 | |
|   let current;
 | |
|   icon = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[0].icon,
 | |
|       style: { "margin-right": "0.2rem" },
 | |
|       clickable: false,
 | |
|       size: 20
 | |
|     }
 | |
|   });
 | |
|   let if_block = ctx[1] && create_if_block2(ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       div2 = element("div");
 | |
|       div0 = element("div");
 | |
|       create_component(icon.$$.fragment);
 | |
|       t0 = space();
 | |
|       span = element("span");
 | |
|       t1 = text(t1_value);
 | |
|       t2 = text("\n		(");
 | |
|       t3 = text(t3_value);
 | |
|       t4 = text(")");
 | |
|       t5 = space();
 | |
|       div1 = element("div");
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       set_style(span, "font-weight", "500");
 | |
|       set_style(span, "margin-right", "0.2rem");
 | |
|       attr(div0, "class", "playlist-item-left svelte-nlujum");
 | |
|       attr(div1, "class", "playlist-item-controls svelte-nlujum");
 | |
|       attr(div2, "class", "playlist-item svelte-nlujum");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div2, anchor);
 | |
|       append(div2, div0);
 | |
|       mount_component(icon, div0, null);
 | |
|       append(div0, t0);
 | |
|       append(div0, span);
 | |
|       append(span, t1);
 | |
|       append(div0, t2);
 | |
|       append(div0, t3);
 | |
|       append(div0, t4);
 | |
|       append(div2, t5);
 | |
|       append(div2, div1);
 | |
|       if (if_block)
 | |
|         if_block.m(div1, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const icon_changes = {};
 | |
|       if (dirty & 1)
 | |
|         icon_changes.icon = ctx2[0].icon;
 | |
|       icon.$set(icon_changes);
 | |
|       if ((!current || dirty & 1) && t1_value !== (t1_value = ctx2[0].name + ""))
 | |
|         set_data(t1, t1_value);
 | |
|       if ((!current || dirty & 1) && t3_value !== (t3_value = ctx2[0].episodes.length + ""))
 | |
|         set_data(t3, t3_value);
 | |
|       if (ctx2[1]) {
 | |
|         if (if_block) {
 | |
|           if_block.p(ctx2, dirty);
 | |
|           if (dirty & 2) {
 | |
|             transition_in(if_block, 1);
 | |
|           }
 | |
|         } else {
 | |
|           if_block = create_if_block2(ctx2);
 | |
|           if_block.c();
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(div1, null);
 | |
|         }
 | |
|       } else if (if_block) {
 | |
|         group_outros();
 | |
|         transition_out(if_block, 1, 1, () => {
 | |
|           if_block = null;
 | |
|         });
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div2);
 | |
|       destroy_component(icon);
 | |
|       if (if_block)
 | |
|         if_block.d();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance6($$self, $$props, $$invalidate) {
 | |
|   let { playlist } = $$props;
 | |
|   let { showDeleteButton = true } = $$props;
 | |
|   let clickedDelete = false;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function onClickedDelete(event) {
 | |
|     if (clickedDelete) {
 | |
|       dispatch2("delete", { value: playlist });
 | |
|       return;
 | |
|     }
 | |
|     $$invalidate(2, clickedDelete = true);
 | |
|     setTimeout(() => {
 | |
|       $$invalidate(2, clickedDelete = false);
 | |
|     }, 2e3);
 | |
|   }
 | |
|   function onClickedRepeat(event) {
 | |
|     dispatch2("toggleRepeat", { value: playlist });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("playlist" in $$props2)
 | |
|       $$invalidate(0, playlist = $$props2.playlist);
 | |
|     if ("showDeleteButton" in $$props2)
 | |
|       $$invalidate(1, showDeleteButton = $$props2.showDeleteButton);
 | |
|   };
 | |
|   return [playlist, showDeleteButton, clickedDelete, onClickedDelete];
 | |
| }
 | |
| var PlaylistItem = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance6, create_fragment6, safe_not_equal, { playlist: 0, showDeleteButton: 1 }, add_css4);
 | |
|   }
 | |
| };
 | |
| var PlaylistItem_default = PlaylistItem;
 | |
| 
 | |
| // src/ui/obsidian/Dropdown.svelte
 | |
| var import_obsidian8 = require("obsidian");
 | |
| function create_fragment7(ctx) {
 | |
|   let span;
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       ctx[5](span);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       ctx[5](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance7($$self, $$props, $$invalidate) {
 | |
|   let { value = "" } = $$props;
 | |
|   let { options = {} } = $$props;
 | |
|   let { disabled = false } = $$props;
 | |
|   let dropdownRef;
 | |
|   let dropdown;
 | |
|   let { style: styles } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   onMount(() => {
 | |
|     dropdown = new import_obsidian8.DropdownComponent(dropdownRef);
 | |
|     updateDropdownAttributes(dropdown);
 | |
|   });
 | |
|   function updateDropdownAttributes(dropdown2) {
 | |
|     if (options)
 | |
|       dropdown2.addOptions(options);
 | |
|     if (value)
 | |
|       dropdown2.setValue(value);
 | |
|     if (disabled)
 | |
|       dropdown2.setDisabled(disabled);
 | |
|     dropdown2.onChange((value2) => {
 | |
|       dispatch2("change", { value: value2 });
 | |
|     });
 | |
|     if (styles) {
 | |
|       dropdown2.selectEl.setAttr("style", extractStylesFromObj(styles));
 | |
|     }
 | |
|   }
 | |
|   function span_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       dropdownRef = $$value;
 | |
|       $$invalidate(0, dropdownRef);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("value" in $$props2)
 | |
|       $$invalidate(1, value = $$props2.value);
 | |
|     if ("options" in $$props2)
 | |
|       $$invalidate(2, options = $$props2.options);
 | |
|     if ("disabled" in $$props2)
 | |
|       $$invalidate(3, disabled = $$props2.disabled);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(4, styles = $$props2.style);
 | |
|   };
 | |
|   return [dropdownRef, value, options, disabled, styles, span_binding];
 | |
| }
 | |
| var Dropdown = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance7, create_fragment7, safe_not_equal, {
 | |
|       value: 1,
 | |
|       options: 2,
 | |
|       disabled: 3,
 | |
|       style: 4
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var Dropdown_default = Dropdown;
 | |
| 
 | |
| // src/ui/settings/PlaylistManager.svelte
 | |
| function add_css5(target) {
 | |
|   append_styles(target, "svelte-46vu4x", ".playlist-manager-container.svelte-46vu4x{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;margin-bottom:2rem}.playlist-list.svelte-46vu4x{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;overflow-y:auto}.add-playlist-container.svelte-46vu4x{margin-top:1rem}");
 | |
| }
 | |
| function get_each_context2(ctx, list, i) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   child_ctx[12] = list[i];
 | |
|   return child_ctx;
 | |
| }
 | |
| function create_each_block2(ctx) {
 | |
|   let playlistitem;
 | |
|   let current;
 | |
|   playlistitem = new PlaylistItem_default({
 | |
|     props: { playlist: ctx[12] }
 | |
|   });
 | |
|   playlistitem.$on("delete", ctx[8]);
 | |
|   playlistitem.$on("toggleRepeat", ctx[9]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(playlistitem.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(playlistitem, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const playlistitem_changes = {};
 | |
|       if (dirty & 1)
 | |
|         playlistitem_changes.playlist = ctx2[12];
 | |
|       playlistitem.$set(playlistitem_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(playlistitem.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(playlistitem.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(playlistitem, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment8(ctx) {
 | |
|   let div2;
 | |
|   let div0;
 | |
|   let playlistitem0;
 | |
|   let t0;
 | |
|   let playlistitem1;
 | |
|   let t1;
 | |
|   let t2;
 | |
|   let div1;
 | |
|   let dropdown;
 | |
|   let updating_value;
 | |
|   let t3;
 | |
|   let text_1;
 | |
|   let updating_value_1;
 | |
|   let t4;
 | |
|   let button;
 | |
|   let current;
 | |
|   playlistitem0 = new PlaylistItem_default({
 | |
|     props: {
 | |
|       playlist: ctx[3],
 | |
|       showDeleteButton: false
 | |
|     }
 | |
|   });
 | |
|   playlistitem1 = new PlaylistItem_default({
 | |
|     props: {
 | |
|       playlist: ctx[4],
 | |
|       showDeleteButton: false
 | |
|     }
 | |
|   });
 | |
|   let each_value = ctx[0];
 | |
|   let each_blocks = [];
 | |
|   for (let i = 0; i < each_value.length; i += 1) {
 | |
|     each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i));
 | |
|   }
 | |
|   const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
 | |
|     each_blocks[i] = null;
 | |
|   });
 | |
|   function dropdown_value_binding(value) {
 | |
|     ctx[10](value);
 | |
|   }
 | |
|   let dropdown_props = { options: ctx[5] };
 | |
|   if (ctx[2] !== void 0) {
 | |
|     dropdown_props.value = ctx[2];
 | |
|   }
 | |
|   dropdown = new Dropdown_default({ props: dropdown_props });
 | |
|   binding_callbacks.push(() => bind(dropdown, "value", dropdown_value_binding));
 | |
|   dropdown.$on("change", ctx[7]);
 | |
|   function text_1_value_binding(value) {
 | |
|     ctx[11](value);
 | |
|   }
 | |
|   let text_1_props = { placeholder: "Playlist name" };
 | |
|   if (ctx[1] !== void 0) {
 | |
|     text_1_props.value = ctx[1];
 | |
|   }
 | |
|   text_1 = new Text_default({ props: text_1_props });
 | |
|   binding_callbacks.push(() => bind(text_1, "value", text_1_value_binding));
 | |
|   button = new Button_default({ props: { icon: "plus", cta: true } });
 | |
|   button.$on("click", ctx[6]);
 | |
|   return {
 | |
|     c() {
 | |
|       div2 = element("div");
 | |
|       div0 = element("div");
 | |
|       create_component(playlistitem0.$$.fragment);
 | |
|       t0 = space();
 | |
|       create_component(playlistitem1.$$.fragment);
 | |
|       t1 = space();
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].c();
 | |
|       }
 | |
|       t2 = space();
 | |
|       div1 = element("div");
 | |
|       create_component(dropdown.$$.fragment);
 | |
|       t3 = space();
 | |
|       create_component(text_1.$$.fragment);
 | |
|       t4 = space();
 | |
|       create_component(button.$$.fragment);
 | |
|       attr(div0, "class", "playlist-list svelte-46vu4x");
 | |
|       attr(div1, "class", "add-playlist-container svelte-46vu4x");
 | |
|       attr(div2, "class", "playlist-manager-container svelte-46vu4x");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div2, anchor);
 | |
|       append(div2, div0);
 | |
|       mount_component(playlistitem0, div0, null);
 | |
|       append(div0, t0);
 | |
|       mount_component(playlistitem1, div0, null);
 | |
|       append(div0, t1);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].m(div0, null);
 | |
|       }
 | |
|       append(div2, t2);
 | |
|       append(div2, div1);
 | |
|       mount_component(dropdown, div1, null);
 | |
|       append(div1, t3);
 | |
|       mount_component(text_1, div1, null);
 | |
|       append(div1, t4);
 | |
|       mount_component(button, div1, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const playlistitem0_changes = {};
 | |
|       if (dirty & 8)
 | |
|         playlistitem0_changes.playlist = ctx2[3];
 | |
|       playlistitem0.$set(playlistitem0_changes);
 | |
|       const playlistitem1_changes = {};
 | |
|       if (dirty & 16)
 | |
|         playlistitem1_changes.playlist = ctx2[4];
 | |
|       playlistitem1.$set(playlistitem1_changes);
 | |
|       if (dirty & 769) {
 | |
|         each_value = ctx2[0];
 | |
|         let i;
 | |
|         for (i = 0; i < each_value.length; i += 1) {
 | |
|           const child_ctx = get_each_context2(ctx2, each_value, i);
 | |
|           if (each_blocks[i]) {
 | |
|             each_blocks[i].p(child_ctx, dirty);
 | |
|             transition_in(each_blocks[i], 1);
 | |
|           } else {
 | |
|             each_blocks[i] = create_each_block2(child_ctx);
 | |
|             each_blocks[i].c();
 | |
|             transition_in(each_blocks[i], 1);
 | |
|             each_blocks[i].m(div0, null);
 | |
|           }
 | |
|         }
 | |
|         group_outros();
 | |
|         for (i = each_value.length; i < each_blocks.length; i += 1) {
 | |
|           out(i);
 | |
|         }
 | |
|         check_outros();
 | |
|       }
 | |
|       const dropdown_changes = {};
 | |
|       if (!updating_value && dirty & 4) {
 | |
|         updating_value = true;
 | |
|         dropdown_changes.value = ctx2[2];
 | |
|         add_flush_callback(() => updating_value = false);
 | |
|       }
 | |
|       dropdown.$set(dropdown_changes);
 | |
|       const text_1_changes = {};
 | |
|       if (!updating_value_1 && dirty & 2) {
 | |
|         updating_value_1 = true;
 | |
|         text_1_changes.value = ctx2[1];
 | |
|         add_flush_callback(() => updating_value_1 = false);
 | |
|       }
 | |
|       text_1.$set(text_1_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(playlistitem0.$$.fragment, local);
 | |
|       transition_in(playlistitem1.$$.fragment, local);
 | |
|       for (let i = 0; i < each_value.length; i += 1) {
 | |
|         transition_in(each_blocks[i]);
 | |
|       }
 | |
|       transition_in(dropdown.$$.fragment, local);
 | |
|       transition_in(text_1.$$.fragment, local);
 | |
|       transition_in(button.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(playlistitem0.$$.fragment, local);
 | |
|       transition_out(playlistitem1.$$.fragment, local);
 | |
|       each_blocks = each_blocks.filter(Boolean);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         transition_out(each_blocks[i]);
 | |
|       }
 | |
|       transition_out(dropdown.$$.fragment, local);
 | |
|       transition_out(text_1.$$.fragment, local);
 | |
|       transition_out(button.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div2);
 | |
|       destroy_component(playlistitem0);
 | |
|       destroy_component(playlistitem1);
 | |
|       destroy_each(each_blocks, detaching);
 | |
|       destroy_component(dropdown);
 | |
|       destroy_component(text_1);
 | |
|       destroy_component(button);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance8($$self, $$props, $$invalidate) {
 | |
|   let $queue;
 | |
|   let $favorites;
 | |
|   component_subscribe($$self, queue, ($$value) => $$invalidate(3, $queue = $$value));
 | |
|   component_subscribe($$self, favorites, ($$value) => $$invalidate(4, $favorites = $$value));
 | |
|   let playlistArr = [];
 | |
|   let playlistInput = "";
 | |
|   let options = ICON_LIST.reduce((acc, curr) => {
 | |
|     acc[curr] = curr;
 | |
|     return acc;
 | |
|   }, {});
 | |
|   let icon = ICON_LIST[0];
 | |
|   onMount(() => {
 | |
|     const unsubscribe = playlists.subscribe((playlists2) => {
 | |
|       $$invalidate(0, playlistArr = Object.values(playlists2));
 | |
|     });
 | |
|     return () => {
 | |
|       unsubscribe();
 | |
|     };
 | |
|   });
 | |
|   function onAddPlaylist() {
 | |
|     playlists.update((value) => {
 | |
|       value[playlistInput] = {
 | |
|         name: playlistInput,
 | |
|         icon,
 | |
|         episodes: [],
 | |
|         shouldEpisodeRemoveAfterPlay: false,
 | |
|         shouldRepeat: false
 | |
|       };
 | |
|       return value;
 | |
|     });
 | |
|     $$invalidate(1, playlistInput = "");
 | |
|     $$invalidate(2, icon = ICON_LIST[0]);
 | |
|   }
 | |
|   function onChangeIcon(event) {
 | |
|     $$invalidate(2, icon = event.detail.value);
 | |
|   }
 | |
|   function onDeletePlaylist(event) {
 | |
|     playlists.update((value) => {
 | |
|       delete value[event.detail.value.name];
 | |
|       return value;
 | |
|     });
 | |
|   }
 | |
|   function onToggleRepeat(event) {
 | |
|     playlists.update((value) => {
 | |
|       value[event.detail.value.name].shouldRepeat = !value[event.detail.value.name].shouldRepeat;
 | |
|       return value;
 | |
|     });
 | |
|   }
 | |
|   function dropdown_value_binding(value) {
 | |
|     icon = value;
 | |
|     $$invalidate(2, icon);
 | |
|   }
 | |
|   function text_1_value_binding(value) {
 | |
|     playlistInput = value;
 | |
|     $$invalidate(1, playlistInput);
 | |
|   }
 | |
|   return [
 | |
|     playlistArr,
 | |
|     playlistInput,
 | |
|     icon,
 | |
|     $queue,
 | |
|     $favorites,
 | |
|     options,
 | |
|     onAddPlaylist,
 | |
|     onChangeIcon,
 | |
|     onDeletePlaylist,
 | |
|     onToggleRepeat,
 | |
|     dropdown_value_binding,
 | |
|     text_1_value_binding
 | |
|   ];
 | |
| }
 | |
| var PlaylistManager = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance8, create_fragment8, safe_not_equal, {}, add_css5);
 | |
|   }
 | |
| };
 | |
| var PlaylistManager_default = PlaylistManager;
 | |
| 
 | |
| // src/TemplateEngine.ts
 | |
| var import_obsidian9 = require("obsidian");
 | |
| 
 | |
| // node_modules/fuse.js/dist/fuse.esm.js
 | |
| function isArray(value) {
 | |
|   return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
 | |
| }
 | |
| var INFINITY = 1 / 0;
 | |
| function baseToString(value) {
 | |
|   if (typeof value == "string") {
 | |
|     return value;
 | |
|   }
 | |
|   let result = value + "";
 | |
|   return result == "0" && 1 / value == -INFINITY ? "-0" : result;
 | |
| }
 | |
| function toString(value) {
 | |
|   return value == null ? "" : baseToString(value);
 | |
| }
 | |
| function isString(value) {
 | |
|   return typeof value === "string";
 | |
| }
 | |
| function isNumber(value) {
 | |
|   return typeof value === "number";
 | |
| }
 | |
| function isBoolean(value) {
 | |
|   return value === true || value === false || isObjectLike(value) && getTag(value) == "[object Boolean]";
 | |
| }
 | |
| function isObject(value) {
 | |
|   return typeof value === "object";
 | |
| }
 | |
| function isObjectLike(value) {
 | |
|   return isObject(value) && value !== null;
 | |
| }
 | |
| function isDefined(value) {
 | |
|   return value !== void 0 && value !== null;
 | |
| }
 | |
| function isBlank(value) {
 | |
|   return !value.trim().length;
 | |
| }
 | |
| function getTag(value) {
 | |
|   return value == null ? value === void 0 ? "[object Undefined]" : "[object Null]" : Object.prototype.toString.call(value);
 | |
| }
 | |
| var INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
 | |
| var LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
 | |
| var PATTERN_LENGTH_TOO_LARGE = (max) => `Pattern length exceeds max of ${max}.`;
 | |
| var MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
 | |
| var INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
 | |
| var hasOwn = Object.prototype.hasOwnProperty;
 | |
| var KeyStore = class {
 | |
|   constructor(keys) {
 | |
|     this._keys = [];
 | |
|     this._keyMap = {};
 | |
|     let totalWeight = 0;
 | |
|     keys.forEach((key) => {
 | |
|       let obj = createKey(key);
 | |
|       totalWeight += obj.weight;
 | |
|       this._keys.push(obj);
 | |
|       this._keyMap[obj.id] = obj;
 | |
|       totalWeight += obj.weight;
 | |
|     });
 | |
|     this._keys.forEach((key) => {
 | |
|       key.weight /= totalWeight;
 | |
|     });
 | |
|   }
 | |
|   get(keyId) {
 | |
|     return this._keyMap[keyId];
 | |
|   }
 | |
|   keys() {
 | |
|     return this._keys;
 | |
|   }
 | |
|   toJSON() {
 | |
|     return JSON.stringify(this._keys);
 | |
|   }
 | |
| };
 | |
| function createKey(key) {
 | |
|   let path = null;
 | |
|   let id = null;
 | |
|   let src = null;
 | |
|   let weight = 1;
 | |
|   let getFn = null;
 | |
|   if (isString(key) || isArray(key)) {
 | |
|     src = key;
 | |
|     path = createKeyPath(key);
 | |
|     id = createKeyId(key);
 | |
|   } else {
 | |
|     if (!hasOwn.call(key, "name")) {
 | |
|       throw new Error(MISSING_KEY_PROPERTY("name"));
 | |
|     }
 | |
|     const name = key.name;
 | |
|     src = name;
 | |
|     if (hasOwn.call(key, "weight")) {
 | |
|       weight = key.weight;
 | |
|       if (weight <= 0) {
 | |
|         throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
 | |
|       }
 | |
|     }
 | |
|     path = createKeyPath(name);
 | |
|     id = createKeyId(name);
 | |
|     getFn = key.getFn;
 | |
|   }
 | |
|   return { path, id, weight, src, getFn };
 | |
| }
 | |
| function createKeyPath(key) {
 | |
|   return isArray(key) ? key : key.split(".");
 | |
| }
 | |
| function createKeyId(key) {
 | |
|   return isArray(key) ? key.join(".") : key;
 | |
| }
 | |
| function get(obj, path) {
 | |
|   let list = [];
 | |
|   let arr = false;
 | |
|   const deepGet = (obj2, path2, index) => {
 | |
|     if (!isDefined(obj2)) {
 | |
|       return;
 | |
|     }
 | |
|     if (!path2[index]) {
 | |
|       list.push(obj2);
 | |
|     } else {
 | |
|       let key = path2[index];
 | |
|       const value = obj2[key];
 | |
|       if (!isDefined(value)) {
 | |
|         return;
 | |
|       }
 | |
|       if (index === path2.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
 | |
|         list.push(toString(value));
 | |
|       } else if (isArray(value)) {
 | |
|         arr = true;
 | |
|         for (let i = 0, len = value.length; i < len; i += 1) {
 | |
|           deepGet(value[i], path2, index + 1);
 | |
|         }
 | |
|       } else if (path2.length) {
 | |
|         deepGet(value, path2, index + 1);
 | |
|       }
 | |
|     }
 | |
|   };
 | |
|   deepGet(obj, isString(path) ? path.split(".") : path, 0);
 | |
|   return arr ? list : list[0];
 | |
| }
 | |
| var MatchOptions = {
 | |
|   includeMatches: false,
 | |
|   findAllMatches: false,
 | |
|   minMatchCharLength: 1
 | |
| };
 | |
| var BasicOptions = {
 | |
|   isCaseSensitive: false,
 | |
|   includeScore: false,
 | |
|   keys: [],
 | |
|   shouldSort: true,
 | |
|   sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
 | |
| };
 | |
| var FuzzyOptions = {
 | |
|   location: 0,
 | |
|   threshold: 0.6,
 | |
|   distance: 100
 | |
| };
 | |
| var AdvancedOptions = {
 | |
|   useExtendedSearch: false,
 | |
|   getFn: get,
 | |
|   ignoreLocation: false,
 | |
|   ignoreFieldNorm: false,
 | |
|   fieldNormWeight: 1
 | |
| };
 | |
| var Config = {
 | |
|   ...BasicOptions,
 | |
|   ...MatchOptions,
 | |
|   ...FuzzyOptions,
 | |
|   ...AdvancedOptions
 | |
| };
 | |
| var SPACE = /[^ ]+/g;
 | |
| function norm(weight = 1, mantissa = 3) {
 | |
|   const cache = /* @__PURE__ */ new Map();
 | |
|   const m = Math.pow(10, mantissa);
 | |
|   return {
 | |
|     get(value) {
 | |
|       const numTokens = value.match(SPACE).length;
 | |
|       if (cache.has(numTokens)) {
 | |
|         return cache.get(numTokens);
 | |
|       }
 | |
|       const norm2 = 1 / Math.pow(numTokens, 0.5 * weight);
 | |
|       const n = parseFloat(Math.round(norm2 * m) / m);
 | |
|       cache.set(numTokens, n);
 | |
|       return n;
 | |
|     },
 | |
|     clear() {
 | |
|       cache.clear();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| var FuseIndex = class {
 | |
|   constructor({
 | |
|     getFn = Config.getFn,
 | |
|     fieldNormWeight = Config.fieldNormWeight
 | |
|   } = {}) {
 | |
|     this.norm = norm(fieldNormWeight, 3);
 | |
|     this.getFn = getFn;
 | |
|     this.isCreated = false;
 | |
|     this.setIndexRecords();
 | |
|   }
 | |
|   setSources(docs = []) {
 | |
|     this.docs = docs;
 | |
|   }
 | |
|   setIndexRecords(records = []) {
 | |
|     this.records = records;
 | |
|   }
 | |
|   setKeys(keys = []) {
 | |
|     this.keys = keys;
 | |
|     this._keysMap = {};
 | |
|     keys.forEach((key, idx) => {
 | |
|       this._keysMap[key.id] = idx;
 | |
|     });
 | |
|   }
 | |
|   create() {
 | |
|     if (this.isCreated || !this.docs.length) {
 | |
|       return;
 | |
|     }
 | |
|     this.isCreated = true;
 | |
|     if (isString(this.docs[0])) {
 | |
|       this.docs.forEach((doc, docIndex) => {
 | |
|         this._addString(doc, docIndex);
 | |
|       });
 | |
|     } else {
 | |
|       this.docs.forEach((doc, docIndex) => {
 | |
|         this._addObject(doc, docIndex);
 | |
|       });
 | |
|     }
 | |
|     this.norm.clear();
 | |
|   }
 | |
|   add(doc) {
 | |
|     const idx = this.size();
 | |
|     if (isString(doc)) {
 | |
|       this._addString(doc, idx);
 | |
|     } else {
 | |
|       this._addObject(doc, idx);
 | |
|     }
 | |
|   }
 | |
|   removeAt(idx) {
 | |
|     this.records.splice(idx, 1);
 | |
|     for (let i = idx, len = this.size(); i < len; i += 1) {
 | |
|       this.records[i].i -= 1;
 | |
|     }
 | |
|   }
 | |
|   getValueForItemAtKeyId(item, keyId) {
 | |
|     return item[this._keysMap[keyId]];
 | |
|   }
 | |
|   size() {
 | |
|     return this.records.length;
 | |
|   }
 | |
|   _addString(doc, docIndex) {
 | |
|     if (!isDefined(doc) || isBlank(doc)) {
 | |
|       return;
 | |
|     }
 | |
|     let record = {
 | |
|       v: doc,
 | |
|       i: docIndex,
 | |
|       n: this.norm.get(doc)
 | |
|     };
 | |
|     this.records.push(record);
 | |
|   }
 | |
|   _addObject(doc, docIndex) {
 | |
|     let record = { i: docIndex, $: {} };
 | |
|     this.keys.forEach((key, keyIndex) => {
 | |
|       let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
 | |
|       if (!isDefined(value)) {
 | |
|         return;
 | |
|       }
 | |
|       if (isArray(value)) {
 | |
|         let subRecords = [];
 | |
|         const stack = [{ nestedArrIndex: -1, value }];
 | |
|         while (stack.length) {
 | |
|           const { nestedArrIndex, value: value2 } = stack.pop();
 | |
|           if (!isDefined(value2)) {
 | |
|             continue;
 | |
|           }
 | |
|           if (isString(value2) && !isBlank(value2)) {
 | |
|             let subRecord = {
 | |
|               v: value2,
 | |
|               i: nestedArrIndex,
 | |
|               n: this.norm.get(value2)
 | |
|             };
 | |
|             subRecords.push(subRecord);
 | |
|           } else if (isArray(value2)) {
 | |
|             value2.forEach((item, k) => {
 | |
|               stack.push({
 | |
|                 nestedArrIndex: k,
 | |
|                 value: item
 | |
|               });
 | |
|             });
 | |
|           } else
 | |
|             ;
 | |
|         }
 | |
|         record.$[keyIndex] = subRecords;
 | |
|       } else if (isString(value) && !isBlank(value)) {
 | |
|         let subRecord = {
 | |
|           v: value,
 | |
|           n: this.norm.get(value)
 | |
|         };
 | |
|         record.$[keyIndex] = subRecord;
 | |
|       }
 | |
|     });
 | |
|     this.records.push(record);
 | |
|   }
 | |
|   toJSON() {
 | |
|     return {
 | |
|       keys: this.keys,
 | |
|       records: this.records
 | |
|     };
 | |
|   }
 | |
| };
 | |
| function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
 | |
|   const myIndex = new FuseIndex({ getFn, fieldNormWeight });
 | |
|   myIndex.setKeys(keys.map(createKey));
 | |
|   myIndex.setSources(docs);
 | |
|   myIndex.create();
 | |
|   return myIndex;
 | |
| }
 | |
| function parseIndex(data, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
 | |
|   const { keys, records } = data;
 | |
|   const myIndex = new FuseIndex({ getFn, fieldNormWeight });
 | |
|   myIndex.setKeys(keys);
 | |
|   myIndex.setIndexRecords(records);
 | |
|   return myIndex;
 | |
| }
 | |
| function computeScore$1(pattern, {
 | |
|   errors = 0,
 | |
|   currentLocation = 0,
 | |
|   expectedLocation = 0,
 | |
|   distance = Config.distance,
 | |
|   ignoreLocation = Config.ignoreLocation
 | |
| } = {}) {
 | |
|   const accuracy = errors / pattern.length;
 | |
|   if (ignoreLocation) {
 | |
|     return accuracy;
 | |
|   }
 | |
|   const proximity = Math.abs(expectedLocation - currentLocation);
 | |
|   if (!distance) {
 | |
|     return proximity ? 1 : accuracy;
 | |
|   }
 | |
|   return accuracy + proximity / distance;
 | |
| }
 | |
| function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
 | |
|   let indices = [];
 | |
|   let start = -1;
 | |
|   let end = -1;
 | |
|   let i = 0;
 | |
|   for (let len = matchmask.length; i < len; i += 1) {
 | |
|     let match = matchmask[i];
 | |
|     if (match && start === -1) {
 | |
|       start = i;
 | |
|     } else if (!match && start !== -1) {
 | |
|       end = i - 1;
 | |
|       if (end - start + 1 >= minMatchCharLength) {
 | |
|         indices.push([start, end]);
 | |
|       }
 | |
|       start = -1;
 | |
|     }
 | |
|   }
 | |
|   if (matchmask[i - 1] && i - start >= minMatchCharLength) {
 | |
|     indices.push([start, i - 1]);
 | |
|   }
 | |
|   return indices;
 | |
| }
 | |
| var MAX_BITS = 32;
 | |
| function search(text2, pattern, patternAlphabet, {
 | |
|   location = Config.location,
 | |
|   distance = Config.distance,
 | |
|   threshold = Config.threshold,
 | |
|   findAllMatches = Config.findAllMatches,
 | |
|   minMatchCharLength = Config.minMatchCharLength,
 | |
|   includeMatches = Config.includeMatches,
 | |
|   ignoreLocation = Config.ignoreLocation
 | |
| } = {}) {
 | |
|   if (pattern.length > MAX_BITS) {
 | |
|     throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
 | |
|   }
 | |
|   const patternLen = pattern.length;
 | |
|   const textLen = text2.length;
 | |
|   const expectedLocation = Math.max(0, Math.min(location, textLen));
 | |
|   let currentThreshold = threshold;
 | |
|   let bestLocation = expectedLocation;
 | |
|   const computeMatches = minMatchCharLength > 1 || includeMatches;
 | |
|   const matchMask = computeMatches ? Array(textLen) : [];
 | |
|   let index;
 | |
|   while ((index = text2.indexOf(pattern, bestLocation)) > -1) {
 | |
|     let score = computeScore$1(pattern, {
 | |
|       currentLocation: index,
 | |
|       expectedLocation,
 | |
|       distance,
 | |
|       ignoreLocation
 | |
|     });
 | |
|     currentThreshold = Math.min(score, currentThreshold);
 | |
|     bestLocation = index + patternLen;
 | |
|     if (computeMatches) {
 | |
|       let i = 0;
 | |
|       while (i < patternLen) {
 | |
|         matchMask[index + i] = 1;
 | |
|         i += 1;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   bestLocation = -1;
 | |
|   let lastBitArr = [];
 | |
|   let finalScore = 1;
 | |
|   let binMax = patternLen + textLen;
 | |
|   const mask = 1 << patternLen - 1;
 | |
|   for (let i = 0; i < patternLen; i += 1) {
 | |
|     let binMin = 0;
 | |
|     let binMid = binMax;
 | |
|     while (binMin < binMid) {
 | |
|       const score2 = computeScore$1(pattern, {
 | |
|         errors: i,
 | |
|         currentLocation: expectedLocation + binMid,
 | |
|         expectedLocation,
 | |
|         distance,
 | |
|         ignoreLocation
 | |
|       });
 | |
|       if (score2 <= currentThreshold) {
 | |
|         binMin = binMid;
 | |
|       } else {
 | |
|         binMax = binMid;
 | |
|       }
 | |
|       binMid = Math.floor((binMax - binMin) / 2 + binMin);
 | |
|     }
 | |
|     binMax = binMid;
 | |
|     let start = Math.max(1, expectedLocation - binMid + 1);
 | |
|     let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
 | |
|     let bitArr = Array(finish + 2);
 | |
|     bitArr[finish + 1] = (1 << i) - 1;
 | |
|     for (let j = finish; j >= start; j -= 1) {
 | |
|       let currentLocation = j - 1;
 | |
|       let charMatch = patternAlphabet[text2.charAt(currentLocation)];
 | |
|       if (computeMatches) {
 | |
|         matchMask[currentLocation] = +!!charMatch;
 | |
|       }
 | |
|       bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
 | |
|       if (i) {
 | |
|         bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
 | |
|       }
 | |
|       if (bitArr[j] & mask) {
 | |
|         finalScore = computeScore$1(pattern, {
 | |
|           errors: i,
 | |
|           currentLocation,
 | |
|           expectedLocation,
 | |
|           distance,
 | |
|           ignoreLocation
 | |
|         });
 | |
|         if (finalScore <= currentThreshold) {
 | |
|           currentThreshold = finalScore;
 | |
|           bestLocation = currentLocation;
 | |
|           if (bestLocation <= expectedLocation) {
 | |
|             break;
 | |
|           }
 | |
|           start = Math.max(1, 2 * expectedLocation - bestLocation);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     const score = computeScore$1(pattern, {
 | |
|       errors: i + 1,
 | |
|       currentLocation: expectedLocation,
 | |
|       expectedLocation,
 | |
|       distance,
 | |
|       ignoreLocation
 | |
|     });
 | |
|     if (score > currentThreshold) {
 | |
|       break;
 | |
|     }
 | |
|     lastBitArr = bitArr;
 | |
|   }
 | |
|   const result = {
 | |
|     isMatch: bestLocation >= 0,
 | |
|     score: Math.max(1e-3, finalScore)
 | |
|   };
 | |
|   if (computeMatches) {
 | |
|     const indices = convertMaskToIndices(matchMask, minMatchCharLength);
 | |
|     if (!indices.length) {
 | |
|       result.isMatch = false;
 | |
|     } else if (includeMatches) {
 | |
|       result.indices = indices;
 | |
|     }
 | |
|   }
 | |
|   return result;
 | |
| }
 | |
| function createPatternAlphabet(pattern) {
 | |
|   let mask = {};
 | |
|   for (let i = 0, len = pattern.length; i < len; i += 1) {
 | |
|     const char = pattern.charAt(i);
 | |
|     mask[char] = (mask[char] || 0) | 1 << len - i - 1;
 | |
|   }
 | |
|   return mask;
 | |
| }
 | |
| var BitapSearch = class {
 | |
|   constructor(pattern, {
 | |
|     location = Config.location,
 | |
|     threshold = Config.threshold,
 | |
|     distance = Config.distance,
 | |
|     includeMatches = Config.includeMatches,
 | |
|     findAllMatches = Config.findAllMatches,
 | |
|     minMatchCharLength = Config.minMatchCharLength,
 | |
|     isCaseSensitive = Config.isCaseSensitive,
 | |
|     ignoreLocation = Config.ignoreLocation
 | |
|   } = {}) {
 | |
|     this.options = {
 | |
|       location,
 | |
|       threshold,
 | |
|       distance,
 | |
|       includeMatches,
 | |
|       findAllMatches,
 | |
|       minMatchCharLength,
 | |
|       isCaseSensitive,
 | |
|       ignoreLocation
 | |
|     };
 | |
|     this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
 | |
|     this.chunks = [];
 | |
|     if (!this.pattern.length) {
 | |
|       return;
 | |
|     }
 | |
|     const addChunk = (pattern2, startIndex) => {
 | |
|       this.chunks.push({
 | |
|         pattern: pattern2,
 | |
|         alphabet: createPatternAlphabet(pattern2),
 | |
|         startIndex
 | |
|       });
 | |
|     };
 | |
|     const len = this.pattern.length;
 | |
|     if (len > MAX_BITS) {
 | |
|       let i = 0;
 | |
|       const remainder = len % MAX_BITS;
 | |
|       const end = len - remainder;
 | |
|       while (i < end) {
 | |
|         addChunk(this.pattern.substr(i, MAX_BITS), i);
 | |
|         i += MAX_BITS;
 | |
|       }
 | |
|       if (remainder) {
 | |
|         const startIndex = len - MAX_BITS;
 | |
|         addChunk(this.pattern.substr(startIndex), startIndex);
 | |
|       }
 | |
|     } else {
 | |
|       addChunk(this.pattern, 0);
 | |
|     }
 | |
|   }
 | |
|   searchIn(text2) {
 | |
|     const { isCaseSensitive, includeMatches } = this.options;
 | |
|     if (!isCaseSensitive) {
 | |
|       text2 = text2.toLowerCase();
 | |
|     }
 | |
|     if (this.pattern === text2) {
 | |
|       let result2 = {
 | |
|         isMatch: true,
 | |
|         score: 0
 | |
|       };
 | |
|       if (includeMatches) {
 | |
|         result2.indices = [[0, text2.length - 1]];
 | |
|       }
 | |
|       return result2;
 | |
|     }
 | |
|     const {
 | |
|       location,
 | |
|       distance,
 | |
|       threshold,
 | |
|       findAllMatches,
 | |
|       minMatchCharLength,
 | |
|       ignoreLocation
 | |
|     } = this.options;
 | |
|     let allIndices = [];
 | |
|     let totalScore = 0;
 | |
|     let hasMatches = false;
 | |
|     this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
 | |
|       const { isMatch, score, indices } = search(text2, pattern, alphabet, {
 | |
|         location: location + startIndex,
 | |
|         distance,
 | |
|         threshold,
 | |
|         findAllMatches,
 | |
|         minMatchCharLength,
 | |
|         includeMatches,
 | |
|         ignoreLocation
 | |
|       });
 | |
|       if (isMatch) {
 | |
|         hasMatches = true;
 | |
|       }
 | |
|       totalScore += score;
 | |
|       if (isMatch && indices) {
 | |
|         allIndices = [...allIndices, ...indices];
 | |
|       }
 | |
|     });
 | |
|     let result = {
 | |
|       isMatch: hasMatches,
 | |
|       score: hasMatches ? totalScore / this.chunks.length : 1
 | |
|     };
 | |
|     if (hasMatches && includeMatches) {
 | |
|       result.indices = allIndices;
 | |
|     }
 | |
|     return result;
 | |
|   }
 | |
| };
 | |
| var BaseMatch = class {
 | |
|   constructor(pattern) {
 | |
|     this.pattern = pattern;
 | |
|   }
 | |
|   static isMultiMatch(pattern) {
 | |
|     return getMatch(pattern, this.multiRegex);
 | |
|   }
 | |
|   static isSingleMatch(pattern) {
 | |
|     return getMatch(pattern, this.singleRegex);
 | |
|   }
 | |
|   search() {
 | |
|   }
 | |
| };
 | |
| function getMatch(pattern, exp) {
 | |
|   const matches = pattern.match(exp);
 | |
|   return matches ? matches[1] : null;
 | |
| }
 | |
| var ExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^="(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^=(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const isMatch = text2 === this.pattern;
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [0, this.pattern.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var InverseExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "inverse-exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^!"(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^!(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const index = text2.indexOf(this.pattern);
 | |
|     const isMatch = index === -1;
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [0, text2.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var PrefixExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "prefix-exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^\^"(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^\^(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const isMatch = text2.startsWith(this.pattern);
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [0, this.pattern.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var InversePrefixExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "inverse-prefix-exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^!\^"(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^!\^(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const isMatch = !text2.startsWith(this.pattern);
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [0, text2.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var SuffixExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "suffix-exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^"(.*)"\$$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^(.*)\$$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const isMatch = text2.endsWith(this.pattern);
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [text2.length - this.pattern.length, text2.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var InverseSuffixExactMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "inverse-suffix-exact";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^!"(.*)"\$$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^!(.*)\$$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     const isMatch = !text2.endsWith(this.pattern);
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices: [0, text2.length - 1]
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var FuzzyMatch = class extends BaseMatch {
 | |
|   constructor(pattern, {
 | |
|     location = Config.location,
 | |
|     threshold = Config.threshold,
 | |
|     distance = Config.distance,
 | |
|     includeMatches = Config.includeMatches,
 | |
|     findAllMatches = Config.findAllMatches,
 | |
|     minMatchCharLength = Config.minMatchCharLength,
 | |
|     isCaseSensitive = Config.isCaseSensitive,
 | |
|     ignoreLocation = Config.ignoreLocation
 | |
|   } = {}) {
 | |
|     super(pattern);
 | |
|     this._bitapSearch = new BitapSearch(pattern, {
 | |
|       location,
 | |
|       threshold,
 | |
|       distance,
 | |
|       includeMatches,
 | |
|       findAllMatches,
 | |
|       minMatchCharLength,
 | |
|       isCaseSensitive,
 | |
|       ignoreLocation
 | |
|     });
 | |
|   }
 | |
|   static get type() {
 | |
|     return "fuzzy";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^"(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     return this._bitapSearch.searchIn(text2);
 | |
|   }
 | |
| };
 | |
| var IncludeMatch = class extends BaseMatch {
 | |
|   constructor(pattern) {
 | |
|     super(pattern);
 | |
|   }
 | |
|   static get type() {
 | |
|     return "include";
 | |
|   }
 | |
|   static get multiRegex() {
 | |
|     return /^'"(.*)"$/;
 | |
|   }
 | |
|   static get singleRegex() {
 | |
|     return /^'(.*)$/;
 | |
|   }
 | |
|   search(text2) {
 | |
|     let location = 0;
 | |
|     let index;
 | |
|     const indices = [];
 | |
|     const patternLen = this.pattern.length;
 | |
|     while ((index = text2.indexOf(this.pattern, location)) > -1) {
 | |
|       location = index + patternLen;
 | |
|       indices.push([index, location - 1]);
 | |
|     }
 | |
|     const isMatch = !!indices.length;
 | |
|     return {
 | |
|       isMatch,
 | |
|       score: isMatch ? 0 : 1,
 | |
|       indices
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var searchers = [
 | |
|   ExactMatch,
 | |
|   IncludeMatch,
 | |
|   PrefixExactMatch,
 | |
|   InversePrefixExactMatch,
 | |
|   InverseSuffixExactMatch,
 | |
|   SuffixExactMatch,
 | |
|   InverseExactMatch,
 | |
|   FuzzyMatch
 | |
| ];
 | |
| var searchersLen = searchers.length;
 | |
| var SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
 | |
| var OR_TOKEN = "|";
 | |
| function parseQuery(pattern, options = {}) {
 | |
|   return pattern.split(OR_TOKEN).map((item) => {
 | |
|     let query = item.trim().split(SPACE_RE).filter((item2) => item2 && !!item2.trim());
 | |
|     let results = [];
 | |
|     for (let i = 0, len = query.length; i < len; i += 1) {
 | |
|       const queryItem = query[i];
 | |
|       let found = false;
 | |
|       let idx = -1;
 | |
|       while (!found && ++idx < searchersLen) {
 | |
|         const searcher = searchers[idx];
 | |
|         let token = searcher.isMultiMatch(queryItem);
 | |
|         if (token) {
 | |
|           results.push(new searcher(token, options));
 | |
|           found = true;
 | |
|         }
 | |
|       }
 | |
|       if (found) {
 | |
|         continue;
 | |
|       }
 | |
|       idx = -1;
 | |
|       while (++idx < searchersLen) {
 | |
|         const searcher = searchers[idx];
 | |
|         let token = searcher.isSingleMatch(queryItem);
 | |
|         if (token) {
 | |
|           results.push(new searcher(token, options));
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return results;
 | |
|   });
 | |
| }
 | |
| var MultiMatchSet = /* @__PURE__ */ new Set([FuzzyMatch.type, IncludeMatch.type]);
 | |
| var ExtendedSearch = class {
 | |
|   constructor(pattern, {
 | |
|     isCaseSensitive = Config.isCaseSensitive,
 | |
|     includeMatches = Config.includeMatches,
 | |
|     minMatchCharLength = Config.minMatchCharLength,
 | |
|     ignoreLocation = Config.ignoreLocation,
 | |
|     findAllMatches = Config.findAllMatches,
 | |
|     location = Config.location,
 | |
|     threshold = Config.threshold,
 | |
|     distance = Config.distance
 | |
|   } = {}) {
 | |
|     this.query = null;
 | |
|     this.options = {
 | |
|       isCaseSensitive,
 | |
|       includeMatches,
 | |
|       minMatchCharLength,
 | |
|       findAllMatches,
 | |
|       ignoreLocation,
 | |
|       location,
 | |
|       threshold,
 | |
|       distance
 | |
|     };
 | |
|     this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
 | |
|     this.query = parseQuery(this.pattern, this.options);
 | |
|   }
 | |
|   static condition(_, options) {
 | |
|     return options.useExtendedSearch;
 | |
|   }
 | |
|   searchIn(text2) {
 | |
|     const query = this.query;
 | |
|     if (!query) {
 | |
|       return {
 | |
|         isMatch: false,
 | |
|         score: 1
 | |
|       };
 | |
|     }
 | |
|     const { includeMatches, isCaseSensitive } = this.options;
 | |
|     text2 = isCaseSensitive ? text2 : text2.toLowerCase();
 | |
|     let numMatches = 0;
 | |
|     let allIndices = [];
 | |
|     let totalScore = 0;
 | |
|     for (let i = 0, qLen = query.length; i < qLen; i += 1) {
 | |
|       const searchers2 = query[i];
 | |
|       allIndices.length = 0;
 | |
|       numMatches = 0;
 | |
|       for (let j = 0, pLen = searchers2.length; j < pLen; j += 1) {
 | |
|         const searcher = searchers2[j];
 | |
|         const { isMatch, indices, score } = searcher.search(text2);
 | |
|         if (isMatch) {
 | |
|           numMatches += 1;
 | |
|           totalScore += score;
 | |
|           if (includeMatches) {
 | |
|             const type = searcher.constructor.type;
 | |
|             if (MultiMatchSet.has(type)) {
 | |
|               allIndices = [...allIndices, ...indices];
 | |
|             } else {
 | |
|               allIndices.push(indices);
 | |
|             }
 | |
|           }
 | |
|         } else {
 | |
|           totalScore = 0;
 | |
|           numMatches = 0;
 | |
|           allIndices.length = 0;
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       if (numMatches) {
 | |
|         let result = {
 | |
|           isMatch: true,
 | |
|           score: totalScore / numMatches
 | |
|         };
 | |
|         if (includeMatches) {
 | |
|           result.indices = allIndices;
 | |
|         }
 | |
|         return result;
 | |
|       }
 | |
|     }
 | |
|     return {
 | |
|       isMatch: false,
 | |
|       score: 1
 | |
|     };
 | |
|   }
 | |
| };
 | |
| var registeredSearchers = [];
 | |
| function register(...args) {
 | |
|   registeredSearchers.push(...args);
 | |
| }
 | |
| function createSearcher(pattern, options) {
 | |
|   for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
 | |
|     let searcherClass = registeredSearchers[i];
 | |
|     if (searcherClass.condition(pattern, options)) {
 | |
|       return new searcherClass(pattern, options);
 | |
|     }
 | |
|   }
 | |
|   return new BitapSearch(pattern, options);
 | |
| }
 | |
| var LogicalOperator = {
 | |
|   AND: "$and",
 | |
|   OR: "$or"
 | |
| };
 | |
| var KeyType = {
 | |
|   PATH: "$path",
 | |
|   PATTERN: "$val"
 | |
| };
 | |
| var isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
 | |
| var isPath = (query) => !!query[KeyType.PATH];
 | |
| var isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
 | |
| var convertToExplicit = (query) => ({
 | |
|   [LogicalOperator.AND]: Object.keys(query).map((key) => ({
 | |
|     [key]: query[key]
 | |
|   }))
 | |
| });
 | |
| function parse(query, options, { auto: auto2 = true } = {}) {
 | |
|   const next = (query2) => {
 | |
|     let keys = Object.keys(query2);
 | |
|     const isQueryPath = isPath(query2);
 | |
|     if (!isQueryPath && keys.length > 1 && !isExpression(query2)) {
 | |
|       return next(convertToExplicit(query2));
 | |
|     }
 | |
|     if (isLeaf(query2)) {
 | |
|       const key = isQueryPath ? query2[KeyType.PATH] : keys[0];
 | |
|       const pattern = isQueryPath ? query2[KeyType.PATTERN] : query2[key];
 | |
|       if (!isString(pattern)) {
 | |
|         throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
 | |
|       }
 | |
|       const obj = {
 | |
|         keyId: createKeyId(key),
 | |
|         pattern
 | |
|       };
 | |
|       if (auto2) {
 | |
|         obj.searcher = createSearcher(pattern, options);
 | |
|       }
 | |
|       return obj;
 | |
|     }
 | |
|     let node = {
 | |
|       children: [],
 | |
|       operator: keys[0]
 | |
|     };
 | |
|     keys.forEach((key) => {
 | |
|       const value = query2[key];
 | |
|       if (isArray(value)) {
 | |
|         value.forEach((item) => {
 | |
|           node.children.push(next(item));
 | |
|         });
 | |
|       }
 | |
|     });
 | |
|     return node;
 | |
|   };
 | |
|   if (!isExpression(query)) {
 | |
|     query = convertToExplicit(query);
 | |
|   }
 | |
|   return next(query);
 | |
| }
 | |
| function computeScore(results, { ignoreFieldNorm = Config.ignoreFieldNorm }) {
 | |
|   results.forEach((result) => {
 | |
|     let totalScore = 1;
 | |
|     result.matches.forEach(({ key, norm: norm2, score }) => {
 | |
|       const weight = key ? key.weight : null;
 | |
|       totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm2));
 | |
|     });
 | |
|     result.score = totalScore;
 | |
|   });
 | |
| }
 | |
| function transformMatches(result, data) {
 | |
|   const matches = result.matches;
 | |
|   data.matches = [];
 | |
|   if (!isDefined(matches)) {
 | |
|     return;
 | |
|   }
 | |
|   matches.forEach((match) => {
 | |
|     if (!isDefined(match.indices) || !match.indices.length) {
 | |
|       return;
 | |
|     }
 | |
|     const { indices, value } = match;
 | |
|     let obj = {
 | |
|       indices,
 | |
|       value
 | |
|     };
 | |
|     if (match.key) {
 | |
|       obj.key = match.key.src;
 | |
|     }
 | |
|     if (match.idx > -1) {
 | |
|       obj.refIndex = match.idx;
 | |
|     }
 | |
|     data.matches.push(obj);
 | |
|   });
 | |
| }
 | |
| function transformScore(result, data) {
 | |
|   data.score = result.score;
 | |
| }
 | |
| function format(results, docs, {
 | |
|   includeMatches = Config.includeMatches,
 | |
|   includeScore = Config.includeScore
 | |
| } = {}) {
 | |
|   const transformers = [];
 | |
|   if (includeMatches)
 | |
|     transformers.push(transformMatches);
 | |
|   if (includeScore)
 | |
|     transformers.push(transformScore);
 | |
|   return results.map((result) => {
 | |
|     const { idx } = result;
 | |
|     const data = {
 | |
|       item: docs[idx],
 | |
|       refIndex: idx
 | |
|     };
 | |
|     if (transformers.length) {
 | |
|       transformers.forEach((transformer) => {
 | |
|         transformer(result, data);
 | |
|       });
 | |
|     }
 | |
|     return data;
 | |
|   });
 | |
| }
 | |
| var Fuse = class {
 | |
|   constructor(docs, options = {}, index) {
 | |
|     this.options = { ...Config, ...options };
 | |
|     if (this.options.useExtendedSearch && false) {
 | |
|       throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
 | |
|     }
 | |
|     this._keyStore = new KeyStore(this.options.keys);
 | |
|     this.setCollection(docs, index);
 | |
|   }
 | |
|   setCollection(docs, index) {
 | |
|     this._docs = docs;
 | |
|     if (index && !(index instanceof FuseIndex)) {
 | |
|       throw new Error(INCORRECT_INDEX_TYPE);
 | |
|     }
 | |
|     this._myIndex = index || createIndex(this.options.keys, this._docs, {
 | |
|       getFn: this.options.getFn,
 | |
|       fieldNormWeight: this.options.fieldNormWeight
 | |
|     });
 | |
|   }
 | |
|   add(doc) {
 | |
|     if (!isDefined(doc)) {
 | |
|       return;
 | |
|     }
 | |
|     this._docs.push(doc);
 | |
|     this._myIndex.add(doc);
 | |
|   }
 | |
|   remove(predicate = () => false) {
 | |
|     const results = [];
 | |
|     for (let i = 0, len = this._docs.length; i < len; i += 1) {
 | |
|       const doc = this._docs[i];
 | |
|       if (predicate(doc, i)) {
 | |
|         this.removeAt(i);
 | |
|         i -= 1;
 | |
|         len -= 1;
 | |
|         results.push(doc);
 | |
|       }
 | |
|     }
 | |
|     return results;
 | |
|   }
 | |
|   removeAt(idx) {
 | |
|     this._docs.splice(idx, 1);
 | |
|     this._myIndex.removeAt(idx);
 | |
|   }
 | |
|   getIndex() {
 | |
|     return this._myIndex;
 | |
|   }
 | |
|   search(query, { limit = -1 } = {}) {
 | |
|     const {
 | |
|       includeMatches,
 | |
|       includeScore,
 | |
|       shouldSort,
 | |
|       sortFn,
 | |
|       ignoreFieldNorm
 | |
|     } = this.options;
 | |
|     let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);
 | |
|     computeScore(results, { ignoreFieldNorm });
 | |
|     if (shouldSort) {
 | |
|       results.sort(sortFn);
 | |
|     }
 | |
|     if (isNumber(limit) && limit > -1) {
 | |
|       results = results.slice(0, limit);
 | |
|     }
 | |
|     return format(results, this._docs, {
 | |
|       includeMatches,
 | |
|       includeScore
 | |
|     });
 | |
|   }
 | |
|   _searchStringList(query) {
 | |
|     const searcher = createSearcher(query, this.options);
 | |
|     const { records } = this._myIndex;
 | |
|     const results = [];
 | |
|     records.forEach(({ v: text2, i: idx, n: norm2 }) => {
 | |
|       if (!isDefined(text2)) {
 | |
|         return;
 | |
|       }
 | |
|       const { isMatch, score, indices } = searcher.searchIn(text2);
 | |
|       if (isMatch) {
 | |
|         results.push({
 | |
|           item: text2,
 | |
|           idx,
 | |
|           matches: [{ score, value: text2, norm: norm2, indices }]
 | |
|         });
 | |
|       }
 | |
|     });
 | |
|     return results;
 | |
|   }
 | |
|   _searchLogical(query) {
 | |
|     const expression = parse(query, this.options);
 | |
|     const evaluate = (node, item, idx) => {
 | |
|       if (!node.children) {
 | |
|         const { keyId, searcher } = node;
 | |
|         const matches = this._findMatches({
 | |
|           key: this._keyStore.get(keyId),
 | |
|           value: this._myIndex.getValueForItemAtKeyId(item, keyId),
 | |
|           searcher
 | |
|         });
 | |
|         if (matches && matches.length) {
 | |
|           return [
 | |
|             {
 | |
|               idx,
 | |
|               item,
 | |
|               matches
 | |
|             }
 | |
|           ];
 | |
|         }
 | |
|         return [];
 | |
|       }
 | |
|       const res = [];
 | |
|       for (let i = 0, len = node.children.length; i < len; i += 1) {
 | |
|         const child = node.children[i];
 | |
|         const result = evaluate(child, item, idx);
 | |
|         if (result.length) {
 | |
|           res.push(...result);
 | |
|         } else if (node.operator === LogicalOperator.AND) {
 | |
|           return [];
 | |
|         }
 | |
|       }
 | |
|       return res;
 | |
|     };
 | |
|     const records = this._myIndex.records;
 | |
|     const resultMap = {};
 | |
|     const results = [];
 | |
|     records.forEach(({ $: item, i: idx }) => {
 | |
|       if (isDefined(item)) {
 | |
|         let expResults = evaluate(expression, item, idx);
 | |
|         if (expResults.length) {
 | |
|           if (!resultMap[idx]) {
 | |
|             resultMap[idx] = { idx, item, matches: [] };
 | |
|             results.push(resultMap[idx]);
 | |
|           }
 | |
|           expResults.forEach(({ matches }) => {
 | |
|             resultMap[idx].matches.push(...matches);
 | |
|           });
 | |
|         }
 | |
|       }
 | |
|     });
 | |
|     return results;
 | |
|   }
 | |
|   _searchObjectList(query) {
 | |
|     const searcher = createSearcher(query, this.options);
 | |
|     const { keys, records } = this._myIndex;
 | |
|     const results = [];
 | |
|     records.forEach(({ $: item, i: idx }) => {
 | |
|       if (!isDefined(item)) {
 | |
|         return;
 | |
|       }
 | |
|       let matches = [];
 | |
|       keys.forEach((key, keyIndex) => {
 | |
|         matches.push(...this._findMatches({
 | |
|           key,
 | |
|           value: item[keyIndex],
 | |
|           searcher
 | |
|         }));
 | |
|       });
 | |
|       if (matches.length) {
 | |
|         results.push({
 | |
|           idx,
 | |
|           item,
 | |
|           matches
 | |
|         });
 | |
|       }
 | |
|     });
 | |
|     return results;
 | |
|   }
 | |
|   _findMatches({ key, value, searcher }) {
 | |
|     if (!isDefined(value)) {
 | |
|       return [];
 | |
|     }
 | |
|     let matches = [];
 | |
|     if (isArray(value)) {
 | |
|       value.forEach(({ v: text2, i: idx, n: norm2 }) => {
 | |
|         if (!isDefined(text2)) {
 | |
|           return;
 | |
|         }
 | |
|         const { isMatch, score, indices } = searcher.searchIn(text2);
 | |
|         if (isMatch) {
 | |
|           matches.push({
 | |
|             score,
 | |
|             key,
 | |
|             value: text2,
 | |
|             idx,
 | |
|             norm: norm2,
 | |
|             indices
 | |
|           });
 | |
|         }
 | |
|       });
 | |
|     } else {
 | |
|       const { v: text2, n: norm2 } = value;
 | |
|       const { isMatch, score, indices } = searcher.searchIn(text2);
 | |
|       if (isMatch) {
 | |
|         matches.push({ score, key, value: text2, norm: norm2, indices });
 | |
|       }
 | |
|     }
 | |
|     return matches;
 | |
|   }
 | |
| };
 | |
| Fuse.version = "6.6.2";
 | |
| Fuse.createIndex = createIndex;
 | |
| Fuse.parseIndex = parseIndex;
 | |
| Fuse.config = Config;
 | |
| {
 | |
|   Fuse.parseQuery = parse;
 | |
| }
 | |
| {
 | |
|   register(ExtendedSearch);
 | |
| }
 | |
| 
 | |
| // src/utility/getUrlExtension.ts
 | |
| function getUrlExtension(url) {
 | |
|   const regexp = new RegExp(/\.([0-9a-z]+)(?:[?#]|$)/i);
 | |
|   const match = regexp.exec(url);
 | |
|   if (!match) {
 | |
|     return "";
 | |
|   }
 | |
|   const [, extension] = match;
 | |
|   return extension;
 | |
| }
 | |
| 
 | |
| // src/TemplateEngine.ts
 | |
| function useTemplateEngine() {
 | |
|   const tags = {};
 | |
|   function addTag(tag, value) {
 | |
|     tags[tag] = value;
 | |
|   }
 | |
|   function replacer(template) {
 | |
|     return template.replace(/\{\{(.*?)(:\s*?.+?)?\}\}/g, (match, tagId, params) => {
 | |
|       const tagValue = tags[tagId.toLowerCase()];
 | |
|       if (tagValue === null || tagValue === void 0) {
 | |
|         const fuse = new Fuse(Object.keys(tags), {
 | |
|           shouldSort: true,
 | |
|           findAllMatches: false,
 | |
|           threshold: 0.4,
 | |
|           isCaseSensitive: false
 | |
|         });
 | |
|         const similarTag = fuse.search(tagId);
 | |
|         new import_obsidian9.Notice(`Tag ${tagId} is invalid.${similarTag.length > 0 ? ` Did you mean ${similarTag[0].item}?` : ""}`);
 | |
|         return match;
 | |
|       }
 | |
|       if (typeof tagValue === "function") {
 | |
|         if (params) {
 | |
|           const splitParams = params.slice(1).split(",");
 | |
|           const args = Array.isArray(splitParams) ? splitParams : [params];
 | |
|           return tagValue(...args);
 | |
|         }
 | |
|         return tagValue();
 | |
|       }
 | |
|       return tagValue;
 | |
|     });
 | |
|   }
 | |
|   return [replacer, addTag];
 | |
| }
 | |
| function NoteTemplateEngine(template, episode) {
 | |
|   const [replacer, addTag] = useTemplateEngine();
 | |
|   addTag("title", episode.title);
 | |
|   addTag("description", (prependToLines) => {
 | |
|     const sanitizeDescription = (0, import_obsidian9.htmlToMarkdown)(episode.description).replace(/\n{3,}/g, "\n\n");
 | |
|     if (prependToLines) {
 | |
|       return sanitizeDescription.split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
 | |
|     }
 | |
|     return sanitizeDescription;
 | |
|   });
 | |
|   addTag("content", (prependToLines) => {
 | |
|     if (prependToLines) {
 | |
|       return (0, import_obsidian9.htmlToMarkdown)(episode.content).split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
 | |
|     }
 | |
|     return (0, import_obsidian9.htmlToMarkdown)(episode.content);
 | |
|   });
 | |
|   addTag("safetitle", replaceIllegalFileNameCharactersInString(episode.title));
 | |
|   addTag("stream", episode.streamUrl);
 | |
|   addTag("url", episode.url);
 | |
|   addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
 | |
|   addTag("podcast", replaceIllegalFileNameCharactersInString(episode.podcastName));
 | |
|   addTag("artwork", episode.artworkUrl ?? "");
 | |
|   return replacer(template);
 | |
| }
 | |
| function TimestampTemplateEngine(template) {
 | |
|   const [replacer, addTag] = useTemplateEngine();
 | |
|   addTag("time", (format2) => get_store_value(plugin).api.getPodcastTimeFormatted(format2 ?? "HH:mm:ss"));
 | |
|   addTag("linktime", (format2) => get_store_value(plugin).api.getPodcastTimeFormatted(format2 ?? "HH:mm:ss", true));
 | |
|   return replacer(template);
 | |
| }
 | |
| function FilePathTemplateEngine(template, episode) {
 | |
|   const [replacer, addTag] = useTemplateEngine();
 | |
|   addTag("title", (whitespaceReplacement) => {
 | |
|     const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalTitle.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalTitle;
 | |
|   });
 | |
|   addTag("podcast", (whitespaceReplacement) => {
 | |
|     const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalName.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalName;
 | |
|   });
 | |
|   addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
 | |
|   return replacer(template);
 | |
| }
 | |
| function DownloadPathTemplateEngine(template, episode) {
 | |
|   const templateExtension = getUrlExtension(template);
 | |
|   const templateWithoutExtension = templateExtension ? template.replace(templateExtension, "") : template;
 | |
|   const [replacer, addTag] = useTemplateEngine();
 | |
|   addTag("title", (whitespaceReplacement) => {
 | |
|     const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalTitle.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalTitle;
 | |
|   });
 | |
|   addTag("podcast", (whitespaceReplacement) => {
 | |
|     const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalName.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalName;
 | |
|   });
 | |
|   addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
 | |
|   return replacer(templateWithoutExtension);
 | |
| }
 | |
| function TranscriptTemplateEngine(template, episode, transcription) {
 | |
|   const [replacer, addTag] = useTemplateEngine();
 | |
|   addTag("title", (whitespaceReplacement) => {
 | |
|     const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalTitle.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalTitle;
 | |
|   });
 | |
|   addTag("podcast", (whitespaceReplacement) => {
 | |
|     const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
 | |
|     if (whitespaceReplacement) {
 | |
|       return legalName.replace(/\s+/g, whitespaceReplacement);
 | |
|     }
 | |
|     return legalName;
 | |
|   });
 | |
|   addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
 | |
|   addTag("transcript", transcription);
 | |
|   addTag("description", (prependToLines) => {
 | |
|     if (prependToLines) {
 | |
|       return (0, import_obsidian9.htmlToMarkdown)(episode.description).split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
 | |
|     }
 | |
|     return (0, import_obsidian9.htmlToMarkdown)(episode.description);
 | |
|   });
 | |
|   addTag("url", episode.url);
 | |
|   addTag("artwork", episode.artworkUrl ?? "");
 | |
|   return replacer(template);
 | |
| }
 | |
| function replaceIllegalFileNameCharactersInString(string) {
 | |
|   return string.replace(/[\\,#%&{}/*<>$'":@\u2023|\\.\?]/g, "").replace(/\n/, " ").replace("  ", " ");
 | |
| }
 | |
| 
 | |
| // src/opml.ts
 | |
| var import_obsidian10 = require("obsidian");
 | |
| function TimerNotice(heading, initialMessage) {
 | |
|   let currentMessage = initialMessage;
 | |
|   const startTime = Date.now();
 | |
|   let stopTime;
 | |
|   const notice = new import_obsidian10.Notice(initialMessage, 0);
 | |
|   function formatMsg(message) {
 | |
|     return `${heading} (${getTime()}):
 | |
| 
 | |
| ${message}`;
 | |
|   }
 | |
|   function update2(message) {
 | |
|     currentMessage = message;
 | |
|     notice.setMessage(formatMsg(currentMessage));
 | |
|   }
 | |
|   const interval = setInterval(() => {
 | |
|     notice.setMessage(formatMsg(currentMessage));
 | |
|   }, 1e3);
 | |
|   function getTime() {
 | |
|     return formatTime(stopTime ? stopTime - startTime : Date.now() - startTime);
 | |
|   }
 | |
|   return {
 | |
|     update: update2,
 | |
|     hide: () => notice.hide(),
 | |
|     stop: () => {
 | |
|       stopTime = Date.now();
 | |
|       clearInterval(interval);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function formatTime(ms) {
 | |
|   const seconds = Math.floor(ms / 1e3);
 | |
|   const minutes = Math.floor(seconds / 60);
 | |
|   const hours = Math.floor(minutes / 60);
 | |
|   return `${hours.toString().padStart(2, "0")}:${(minutes % 60).toString().padStart(2, "0")}:${(seconds % 60).toString().padStart(2, "0")}`;
 | |
| }
 | |
| async function importOPML(opml) {
 | |
|   try {
 | |
|     const dp = new DOMParser();
 | |
|     const dom = dp.parseFromString(opml, "application/xml");
 | |
|     if (dom.documentElement.nodeName === "parsererror") {
 | |
|       throw new Error("Invalid XML format");
 | |
|     }
 | |
|     const podcastEntryNodes = dom.querySelectorAll("outline[text][xmlUrl]");
 | |
|     const incompletePodcastsToAdd = [];
 | |
|     for (let i = 0; i < podcastEntryNodes.length; i++) {
 | |
|       const node = podcastEntryNodes.item(i);
 | |
|       const text2 = node.getAttribute("text");
 | |
|       const xmlUrl = node.getAttribute("xmlUrl");
 | |
|       if (!text2 || !xmlUrl) {
 | |
|         continue;
 | |
|       }
 | |
|       incompletePodcastsToAdd.push({
 | |
|         title: text2,
 | |
|         url: xmlUrl
 | |
|       });
 | |
|     }
 | |
|     if (incompletePodcastsToAdd.length === 0) {
 | |
|       throw new Error("No valid podcast entries found in OPML");
 | |
|     }
 | |
|     const existingSavedFeeds = get_store_value(savedFeeds);
 | |
|     const newPodcastsToAdd = incompletePodcastsToAdd.filter((pod) => !Object.values(existingSavedFeeds).some((savedPod) => savedPod.url === pod.url));
 | |
|     const notice = TimerNotice("Importing podcasts", "Preparing to import...");
 | |
|     let completedImports = 0;
 | |
|     const updateProgress = () => {
 | |
|       const progress = (completedImports / newPodcastsToAdd.length * 100).toFixed(1);
 | |
|       notice.update(`Importing... ${completedImports}/${newPodcastsToAdd.length} podcasts completed (${progress}%)`);
 | |
|     };
 | |
|     updateProgress();
 | |
|     const podcasts = await Promise.all(newPodcastsToAdd.map(async (feed) => {
 | |
|       try {
 | |
|         const result = await new FeedParser().getFeed(feed.url);
 | |
|         completedImports++;
 | |
|         updateProgress();
 | |
|         return result;
 | |
|       } catch (error) {
 | |
|         console.error(`Failed to fetch feed for ${feed.title}: ${error}`);
 | |
|         completedImports++;
 | |
|         updateProgress();
 | |
|         return null;
 | |
|       }
 | |
|     }));
 | |
|     notice.stop();
 | |
|     const validPodcasts = podcasts.filter((pod) => pod !== null);
 | |
|     savedFeeds.update((feeds) => {
 | |
|       for (const pod of validPodcasts) {
 | |
|         if (feeds[pod.title])
 | |
|           continue;
 | |
|         feeds[pod.title] = structuredClone(pod);
 | |
|       }
 | |
|       return feeds;
 | |
|     });
 | |
|     const skippedCount = incompletePodcastsToAdd.length - newPodcastsToAdd.length;
 | |
|     notice.update(`OPML import complete. Saved ${validPodcasts.length} new podcasts. Skipped ${skippedCount} existing podcasts.`);
 | |
|     if (validPodcasts.length !== newPodcastsToAdd.length) {
 | |
|       const failedImports = newPodcastsToAdd.length - validPodcasts.length;
 | |
|       console.error(`Failed to import ${failedImports} podcasts.`);
 | |
|       new import_obsidian10.Notice(`Failed to import ${failedImports} podcasts. Check console for details.`, 1e4);
 | |
|     }
 | |
|     setTimeout(() => notice.hide(), 5e3);
 | |
|   } catch (error) {
 | |
|     console.error("Error importing OPML:", error);
 | |
|     new import_obsidian10.Notice(`Error importing OPML: ${error instanceof Error ? error.message : "Unknown error"}`, 1e4);
 | |
|   }
 | |
| }
 | |
| async function exportOPML(app2, feeds, filePath = "PodNotes_Export.opml") {
 | |
|   const header = `<?xml version="1.0" encoding="utf=8" standalone="no"?>`;
 | |
|   const opml = (child) => `<opml version="1.0">${child}</opml>`;
 | |
|   const head = (child) => `<head>${child}</head>`;
 | |
|   const title = "<title>PodNotes Feeds</title>";
 | |
|   const body = (child) => `<body>${child}</body>`;
 | |
|   const feedOutline = (feed) => `<outline text="${feed.title}" type="rss" xmlUrl="${feed.url}" />`;
 | |
|   const feedsOutline = (_feeds) => `<outline text="feeds">${feeds.map(feedOutline).join("")}</outline>`;
 | |
|   const doc = header + opml(`${head(title)}
 | |
| ${body(feedsOutline(feeds))}`);
 | |
|   try {
 | |
|     await app2.vault.create(filePath, doc);
 | |
|     new import_obsidian10.Notice(`Exported ${feeds.length} podcast feeds to file "${filePath}".`);
 | |
|   } catch (error) {
 | |
|     if (error instanceof Error) {
 | |
|       if (error.message.includes("Folder does not exist")) {
 | |
|         new import_obsidian10.Notice("Unable to create export file: Folder does not exist.");
 | |
|       } else {
 | |
|         new import_obsidian10.Notice(`Unable to create podcast export file:
 | |
| 
 | |
| ${error.message}`);
 | |
|       }
 | |
|     } else {
 | |
|       new import_obsidian10.Notice("An unexpected error occurred during export.");
 | |
|     }
 | |
|     console.error(error);
 | |
|   }
 | |
| }
 | |
| 
 | |
| // src/ui/settings/PodNotesSettingsTab.ts
 | |
| var import_obsidian12 = require("obsidian");
 | |
| var PodNotesSettingsTab = class extends import_obsidian11.PluginSettingTab {
 | |
|   constructor(app2, plugin2) {
 | |
|     super(app2, plugin2);
 | |
|     this.plugin = plugin2;
 | |
|     this.settingsTab = this;
 | |
|   }
 | |
|   display() {
 | |
|     const { containerEl } = this;
 | |
|     containerEl.empty();
 | |
|     const header = containerEl.createEl("h2", { text: "PodNotes" });
 | |
|     header.style.textAlign = "center";
 | |
|     const settingsContainer = containerEl.createDiv();
 | |
|     settingsContainer.classList.add("settings-container");
 | |
|     new import_obsidian11.Setting(settingsContainer).setName("Search Podcasts").setHeading().setDesc("Search for podcasts by name or custom feed URL.");
 | |
|     const queryGridContainer = settingsContainer.createDiv();
 | |
|     this.podcastQueryGrid = new PodcastQueryGrid_default({
 | |
|       target: queryGridContainer
 | |
|     });
 | |
|     new import_obsidian11.Setting(settingsContainer).setName("Playlists").setHeading().setDesc("Add playlists to gather podcast episodes.");
 | |
|     const playlistManagerContainer = settingsContainer.createDiv();
 | |
|     this.playlistManager = new PlaylistManager_default({
 | |
|       target: playlistManagerContainer
 | |
|     });
 | |
|     this.addDefaultPlaybackRateSetting(settingsContainer);
 | |
|     this.addSkipLengthSettings(settingsContainer);
 | |
|     this.addNoteSettings(settingsContainer);
 | |
|     this.addDownloadSettings(settingsContainer);
 | |
|     this.addImportExportSettings(settingsContainer);
 | |
|     this.addTranscriptSettings(settingsContainer);
 | |
|   }
 | |
|   hide() {
 | |
|     this.podcastQueryGrid?.$destroy();
 | |
|     this.playlistManager?.$destroy();
 | |
|   }
 | |
|   addDefaultPlaybackRateSetting(container) {
 | |
|     new import_obsidian11.Setting(container).setName("Default Playback Rate").addSlider((slider) => slider.setLimits(0.5, 4, 0.1).setValue(this.plugin.settings.defaultPlaybackRate).onChange((value) => {
 | |
|       this.plugin.settings.defaultPlaybackRate = value;
 | |
|       this.plugin.saveSettings();
 | |
|     }).setDynamicTooltip());
 | |
|   }
 | |
|   addSkipLengthSettings(container) {
 | |
|     new import_obsidian11.Setting(container).setName("Skip backward length (s)").addText((textComponent) => {
 | |
|       textComponent.inputEl.type = "number";
 | |
|       textComponent.setValue(`${this.plugin.settings.skipBackwardLength}`).onChange((value) => {
 | |
|         this.plugin.settings.skipBackwardLength = Number.parseInt(value);
 | |
|         this.plugin.saveSettings();
 | |
|       }).setPlaceholder("seconds");
 | |
|     });
 | |
|     new import_obsidian11.Setting(container).setName("Skip forward length (s)").addText((textComponent) => {
 | |
|       textComponent.inputEl.type = "number";
 | |
|       textComponent.setValue(`${this.plugin.settings.skipForwardLength}`).onChange((value) => {
 | |
|         this.plugin.settings.skipForwardLength = Number.parseInt(value);
 | |
|         this.plugin.saveSettings();
 | |
|       }).setPlaceholder("seconds");
 | |
|     });
 | |
|   }
 | |
|   addNoteSettings(settingsContainer) {
 | |
|     const container = settingsContainer.createDiv();
 | |
|     container.createEl("h4", { text: "Note settings" });
 | |
|     const timestampSetting = new import_obsidian11.Setting(container).setName("Capture timestamp format").setHeading().addTextArea((textArea) => {
 | |
|       textArea.setValue(this.plugin.settings.timestamp.template);
 | |
|       textArea.setPlaceholder("- {{linktime}} ");
 | |
|       textArea.onChange((value) => {
 | |
|         this.plugin.settings.timestamp.template = value;
 | |
|         this.plugin.saveSettings();
 | |
|         updateTimestampDemo(value);
 | |
|       });
 | |
|       textArea.inputEl.style.width = "100%";
 | |
|     });
 | |
|     timestampSetting.settingEl.style.flexDirection = "column";
 | |
|     timestampSetting.settingEl.style.alignItems = "unset";
 | |
|     timestampSetting.settingEl.style.gap = "10px";
 | |
|     const timestampFormatDemoEl = container.createDiv();
 | |
|     const updateTimestampDemo = (value) => {
 | |
|       if (!this.plugin.api.podcast)
 | |
|         return;
 | |
|       const demoVal = TimestampTemplateEngine(value);
 | |
|       timestampFormatDemoEl.empty();
 | |
|       import_obsidian11.MarkdownRenderer.renderMarkdown(demoVal, timestampFormatDemoEl, "", new import_obsidian12.Component());
 | |
|     };
 | |
|     updateTimestampDemo(this.plugin.settings.timestamp.template);
 | |
|     const randomEpisode = getRandomEpisode();
 | |
|     const noteCreationFilePathSetting = new import_obsidian11.Setting(container).setName("Note creation file path").setHeading().addText((textComponent) => {
 | |
|       textComponent.setValue(this.plugin.settings.note.path);
 | |
|       textComponent.setPlaceholder("inputs/podcasts/{{podcast}} - {{title}}.md");
 | |
|       textComponent.onChange((value) => {
 | |
|         this.plugin.settings.note.path = value;
 | |
|         this.plugin.saveSettings();
 | |
|         const demoVal = FilePathTemplateEngine(value, randomEpisode);
 | |
|         noteCreationFilePathDemoEl.empty();
 | |
|         import_obsidian11.MarkdownRenderer.renderMarkdown(demoVal, noteCreationFilePathDemoEl, "", new import_obsidian12.Component());
 | |
|       });
 | |
|       textComponent.inputEl.style.width = "100%";
 | |
|     });
 | |
|     noteCreationFilePathSetting.settingEl.style.flexDirection = "column";
 | |
|     noteCreationFilePathSetting.settingEl.style.alignItems = "unset";
 | |
|     noteCreationFilePathSetting.settingEl.style.gap = "10px";
 | |
|     const noteCreationFilePathDemoEl = container.createDiv();
 | |
|     const noteCreationSetting = new import_obsidian11.Setting(container).setName("Note creation template").setHeading().addTextArea((textArea) => {
 | |
|       textArea.setValue(this.plugin.settings.note.template);
 | |
|       textArea.onChange((value) => {
 | |
|         this.plugin.settings.note.template = value;
 | |
|         this.plugin.saveSettings();
 | |
|       });
 | |
|       textArea.inputEl.style.width = "100%";
 | |
|       textArea.inputEl.style.height = "25vh";
 | |
|       textArea.setPlaceholder("## {{title}}\n\n### Metadata\nPodcast:: {{podcast}}\nEpisode:: {{title}}\nPublishDate:: {{date:YYYY-MM-DD}}\n### Description\n> {{description}}");
 | |
|     });
 | |
|     noteCreationSetting.settingEl.style.flexDirection = "column";
 | |
|     noteCreationSetting.settingEl.style.alignItems = "unset";
 | |
|     noteCreationSetting.settingEl.style.gap = "10px";
 | |
|   }
 | |
|   addDownloadSettings(container) {
 | |
|     container.createEl("h4", { text: "Download settings" });
 | |
|     const randomEpisode = getRandomEpisode();
 | |
|     const downloadPathSetting = new import_obsidian11.Setting(container).setName("Episode download path").setDesc("The path where the episode will be downloaded to. Avoid setting an extension, as it will be added automatically.").setHeading().addText((textComponent) => {
 | |
|       textComponent.setValue(this.plugin.settings.download.path);
 | |
|       textComponent.setPlaceholder("inputs/podcasts/{{podcast}} - {{title}}");
 | |
|       textComponent.onChange((value) => {
 | |
|         this.plugin.settings.download.path = value;
 | |
|         this.plugin.saveSettings();
 | |
|         const demoVal = DownloadPathTemplateEngine(value, randomEpisode);
 | |
|         downloadFilePathDemoEl.empty();
 | |
|         import_obsidian11.MarkdownRenderer.renderMarkdown(`${demoVal}.mp3`, downloadFilePathDemoEl, "", new import_obsidian12.Component());
 | |
|       });
 | |
|       textComponent.inputEl.style.width = "100%";
 | |
|     });
 | |
|     downloadPathSetting.settingEl.style.flexDirection = "column";
 | |
|     downloadPathSetting.settingEl.style.alignItems = "unset";
 | |
|     downloadPathSetting.settingEl.style.gap = "10px";
 | |
|     const downloadFilePathDemoEl = container.createDiv();
 | |
|   }
 | |
|   addImportExportSettings(containerEl) {
 | |
|     containerEl.createEl("h3", { text: "Import/Export" });
 | |
|     new import_obsidian11.Setting(containerEl).setName("Import OPML").setDesc("Import podcasts from an OPML file.").addButton((button) => button.setButtonText("Import").onClick(() => {
 | |
|       const fileInput = document.createElement("input");
 | |
|       fileInput.type = "file";
 | |
|       fileInput.accept = ".opml";
 | |
|       fileInput.style.display = "none";
 | |
|       document.body.appendChild(fileInput);
 | |
|       fileInput.click();
 | |
|       fileInput.onchange = async (e) => {
 | |
|         const target = e.target;
 | |
|         const file = target.files?.[0];
 | |
|         if (file) {
 | |
|           const reader = new FileReader();
 | |
|           reader.onload = async (event) => {
 | |
|             const contents = event.target?.result;
 | |
|             if (contents) {
 | |
|               try {
 | |
|                 await importOPML(contents);
 | |
|               } catch (e2) {
 | |
|                 console.error("Error importing OPML:", e2);
 | |
|                 new import_obsidian11.Notice(`Error importing OPML: ${e2 instanceof Error ? e2.message : "Unknown error"}`, 1e4);
 | |
|               }
 | |
|             }
 | |
|           };
 | |
|           reader.readAsText(file);
 | |
|         } else {
 | |
|           new import_obsidian11.Notice("No file selected");
 | |
|         }
 | |
|       };
 | |
|     }));
 | |
|     let exportFilePath = "PodNotes_Export.opml";
 | |
|     new import_obsidian11.Setting(containerEl).setName("Export OPML").setDesc("Export saved podcast feeds to an OPML file.").addText((text2) => text2.setPlaceholder("Export file name").setValue(exportFilePath).onChange((value) => {
 | |
|       exportFilePath = value;
 | |
|     })).addButton((button) => button.setButtonText("Export").onClick(() => {
 | |
|       const feeds = Object.values(get_store_value(savedFeeds));
 | |
|       if (feeds.length === 0) {
 | |
|         new import_obsidian11.Notice("No podcasts to export.");
 | |
|         return;
 | |
|       }
 | |
|       exportOPML(this.app, feeds, exportFilePath.endsWith(".opml") ? exportFilePath : `${exportFilePath}.opml`);
 | |
|     }));
 | |
|   }
 | |
|   addTranscriptSettings(container) {
 | |
|     container.createEl("h4", { text: "Transcript settings" });
 | |
|     const randomEpisode = getRandomEpisode();
 | |
|     new import_obsidian11.Setting(container).setName("OpenAI API Key").setDesc("Enter your OpenAI API key for transcription functionality.").addText((text2) => {
 | |
|       text2.setPlaceholder("Enter your OpenAI API key").setValue(this.plugin.settings.openAIApiKey).onChange(async (value) => {
 | |
|         this.plugin.settings.openAIApiKey = value;
 | |
|         await this.plugin.saveSettings();
 | |
|       });
 | |
|       text2.inputEl.type = "password";
 | |
|     });
 | |
|     const transcriptFilePathSetting = new import_obsidian11.Setting(container).setName("Transcript file path").setDesc("The path where transcripts will be saved. Use {{}} for dynamic values.").addText((text2) => {
 | |
|       text2.setPlaceholder("transcripts/{{podcast}}/{{title}}.md").setValue(this.plugin.settings.transcript.path).onChange(async (value) => {
 | |
|         this.plugin.settings.transcript.path = value;
 | |
|         await this.plugin.saveSettings();
 | |
|         updateTranscriptPathDemo(value);
 | |
|       });
 | |
|     });
 | |
|     const transcriptPathDemoEl = container.createDiv();
 | |
|     const updateTranscriptPathDemo = (value) => {
 | |
|       const demoVal = FilePathTemplateEngine(value, randomEpisode);
 | |
|       transcriptPathDemoEl.empty();
 | |
|       transcriptPathDemoEl.createEl("p", { text: `Example: ${demoVal}` });
 | |
|     };
 | |
|     updateTranscriptPathDemo(this.plugin.settings.transcript.path);
 | |
|     const transcriptTemplateSetting = new import_obsidian11.Setting(container).setName("Transcript template").setDesc("The template for the transcript file content.").setHeading().addTextArea((text2) => {
 | |
|       text2.setPlaceholder("# {{title}}\n\nPodcast: {{podcast}}\nDate: {{date}}\nURL: {{url}}\n\n## Description\n\n{{description}}\n\n## Transcript\n\n{{transcript}}").setValue(this.plugin.settings.transcript.template).onChange(async (value) => {
 | |
|         this.plugin.settings.transcript.template = value;
 | |
|         await this.plugin.saveSettings();
 | |
|       });
 | |
|       text2.inputEl.style.width = "100%";
 | |
|       text2.inputEl.style.height = "25vh";
 | |
|     });
 | |
|     transcriptTemplateSetting.settingEl.style.flexDirection = "column";
 | |
|     transcriptTemplateSetting.settingEl.style.alignItems = "unset";
 | |
|     transcriptTemplateSetting.settingEl.style.gap = "10px";
 | |
|   }
 | |
| };
 | |
| function getRandomEpisode() {
 | |
|   const fallbackDemoObj = {
 | |
|     description: "demo",
 | |
|     content: "demo",
 | |
|     podcastName: "demo",
 | |
|     title: "demo",
 | |
|     url: "demo",
 | |
|     artworkUrl: "demo",
 | |
|     streamUrl: "demo",
 | |
|     episodeDate: new Date(),
 | |
|     feedUrl: "demo"
 | |
|   };
 | |
|   const feedEpisodes = Object.values(get_store_value(episodeCache));
 | |
|   if (!feedEpisodes.length)
 | |
|     return fallbackDemoObj;
 | |
|   const randomFeed = feedEpisodes[Math.floor(Math.random() * feedEpisodes.length)];
 | |
|   if (!randomFeed.length)
 | |
|     return fallbackDemoObj;
 | |
|   const randomEpisode = randomFeed[Math.floor(Math.random() * randomFeed.length)];
 | |
|   return randomEpisode;
 | |
| }
 | |
| 
 | |
| // src/ui/PodcastView/index.ts
 | |
| var import_obsidian19 = require("obsidian");
 | |
| 
 | |
| // src/ui/PodcastView/PlaylistCard.svelte
 | |
| function add_css6(target) {
 | |
|   append_styles(target, "svelte-r5cl0s", ".playlist-card.svelte-r5cl0s{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;cursor:pointer;border:1px solid var(--background-modifier-border);text-align:center;overflow:hidden}.playlist-card.svelte-r5cl0s:hover{background-color:var(--background-modifier-border)}");
 | |
| }
 | |
| function create_fragment9(ctx) {
 | |
|   let div;
 | |
|   let icon;
 | |
|   let t0;
 | |
|   let span;
 | |
|   let t1;
 | |
|   let t2_value = ctx[0].episodes.length + "";
 | |
|   let t2;
 | |
|   let t3;
 | |
|   let div_aria_label_value;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   icon = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[0].icon,
 | |
|       size: 40,
 | |
|       clickable: true
 | |
|     }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(icon.$$.fragment);
 | |
|       t0 = space();
 | |
|       span = element("span");
 | |
|       t1 = text("(");
 | |
|       t2 = text(t2_value);
 | |
|       t3 = text(")");
 | |
|       attr(div, "class", "playlist-card svelte-r5cl0s");
 | |
|       attr(div, "aria-label", div_aria_label_value = ctx[0].name);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(icon, div, null);
 | |
|       append(div, t0);
 | |
|       append(div, span);
 | |
|       append(span, t1);
 | |
|       append(span, t2);
 | |
|       append(span, t3);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = listen(div, "click", ctx[1]);
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const icon_changes = {};
 | |
|       if (dirty & 1)
 | |
|         icon_changes.icon = ctx2[0].icon;
 | |
|       icon.$set(icon_changes);
 | |
|       if ((!current || dirty & 1) && t2_value !== (t2_value = ctx2[0].episodes.length + ""))
 | |
|         set_data(t2, t2_value);
 | |
|       if (!current || dirty & 1 && div_aria_label_value !== (div_aria_label_value = ctx2[0].name)) {
 | |
|         attr(div, "aria-label", div_aria_label_value);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(icon);
 | |
|       mounted = false;
 | |
|       dispose();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance9($$self, $$props, $$invalidate) {
 | |
|   let { playlist } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function onClickPlaylist(event) {
 | |
|     dispatch2("clickPlaylist", { playlist, event });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("playlist" in $$props2)
 | |
|       $$invalidate(0, playlist = $$props2.playlist);
 | |
|   };
 | |
|   return [playlist, onClickPlaylist];
 | |
| }
 | |
| var PlaylistCard = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance9, create_fragment9, safe_not_equal, { playlist: 0 }, add_css6);
 | |
|   }
 | |
| };
 | |
| var PlaylistCard_default = PlaylistCard;
 | |
| 
 | |
| // src/ui/common/Image.svelte
 | |
| function add_css7(target) {
 | |
|   append_styles(target, "svelte-1uzaahv", "img.svelte-1uzaahv:hover{cursor:pointer !important}.pn_image_container.svelte-1uzaahv{width:100%;height:100%;display:block;position:relative;overflow:hidden}");
 | |
| }
 | |
| var get_fallback_slot_changes = (dirty) => ({});
 | |
| var get_fallback_slot_context = (ctx) => ({});
 | |
| function create_if_block_1(ctx) {
 | |
|   let current;
 | |
|   const fallback_slot_template = ctx[10].fallback;
 | |
|   const fallback_slot = create_slot(fallback_slot_template, ctx, ctx[9], get_fallback_slot_context);
 | |
|   return {
 | |
|     c() {
 | |
|       if (fallback_slot)
 | |
|         fallback_slot.c();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       if (fallback_slot) {
 | |
|         fallback_slot.m(target, anchor);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (fallback_slot) {
 | |
|         if (fallback_slot.p && (!current || dirty & 512)) {
 | |
|           update_slot_base(fallback_slot, fallback_slot_template, ctx2, ctx2[9], !current ? get_all_dirty_from_scope(ctx2[9]) : get_slot_changes(fallback_slot_template, ctx2[9], dirty, get_fallback_slot_changes), get_fallback_slot_context);
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(fallback_slot, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(fallback_slot, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (fallback_slot)
 | |
|         fallback_slot.d(detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block3(ctx) {
 | |
|   let div;
 | |
|   let img;
 | |
|   let img_src_value;
 | |
|   let img_class_value;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       img = element("img");
 | |
|       attr(img, "draggable", "false");
 | |
|       if (!src_url_equal(img.src, img_src_value = ctx[0]))
 | |
|         attr(img, "src", img_src_value);
 | |
|       attr(img, "alt", ctx[1]);
 | |
|       attr(img, "class", img_class_value = null_to_empty(ctx[4]) + " svelte-1uzaahv");
 | |
|       set_style(img, "opacity", ctx[3] ? ctx[3] : !ctx[2] ? 1 : ctx[5] ? 1 : 0, false);
 | |
|       set_style(img, "transition", ctx[2] ? "opacity 0.5s ease-out" : "", false);
 | |
|       attr(div, "class", "pn_image_container svelte-1uzaahv");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       append(div, img);
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(img, "click", ctx[11]),
 | |
|           listen(img, "load", ctx[12]),
 | |
|           listen(img, "error", ctx[13])
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (dirty & 1 && !src_url_equal(img.src, img_src_value = ctx2[0])) {
 | |
|         attr(img, "src", img_src_value);
 | |
|       }
 | |
|       if (dirty & 2) {
 | |
|         attr(img, "alt", ctx2[1]);
 | |
|       }
 | |
|       if (dirty & 16 && img_class_value !== (img_class_value = null_to_empty(ctx2[4]) + " svelte-1uzaahv")) {
 | |
|         attr(img, "class", img_class_value);
 | |
|       }
 | |
|       if (dirty & 44) {
 | |
|         set_style(img, "opacity", ctx2[3] ? ctx2[3] : !ctx2[2] ? 1 : ctx2[5] ? 1 : 0, false);
 | |
|       }
 | |
|       if (dirty & 4) {
 | |
|         set_style(img, "transition", ctx2[2] ? "opacity 0.5s ease-out" : "", false);
 | |
|       }
 | |
|     },
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment10(ctx) {
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let if_block_anchor;
 | |
|   let current;
 | |
|   const if_block_creators = [create_if_block3, create_if_block_1];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[6] || ctx2[5])
 | |
|       return 0;
 | |
|     if (ctx2[7])
 | |
|       return 1;
 | |
|     return -1;
 | |
|   }
 | |
|   if (~(current_block_type_index = select_block_type(ctx, -1))) {
 | |
|     if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   }
 | |
|   return {
 | |
|     c() {
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       if_block_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].m(target, anchor);
 | |
|       }
 | |
|       insert(target, if_block_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if (~current_block_type_index) {
 | |
|           if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|         }
 | |
|       } else {
 | |
|         if (if_block) {
 | |
|           group_outros();
 | |
|           transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|             if_blocks[previous_block_index] = null;
 | |
|           });
 | |
|           check_outros();
 | |
|         }
 | |
|         if (~current_block_type_index) {
 | |
|           if_block = if_blocks[current_block_type_index];
 | |
|           if (!if_block) {
 | |
|             if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|             if_block.c();
 | |
|           } else {
 | |
|             if_block.p(ctx2, dirty);
 | |
|           }
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(if_block_anchor.parentNode, if_block_anchor);
 | |
|         } else {
 | |
|           if_block = null;
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].d(detaching);
 | |
|       }
 | |
|       if (detaching)
 | |
|         detach(if_block_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance10($$self, $$props, $$invalidate) {
 | |
|   let { $$slots: slots = {}, $$scope } = $$props;
 | |
|   let { src } = $$props;
 | |
|   let { alt } = $$props;
 | |
|   let { fadeIn = false } = $$props;
 | |
|   let { opacity = 0 } = $$props;
 | |
|   let { class: _class = "" } = $$props;
 | |
|   let loaded = false;
 | |
|   let loading = true;
 | |
|   let failed = false;
 | |
|   const dispatcher = createEventDispatcher();
 | |
|   function onClick(event) {
 | |
|     dispatcher("click", { event });
 | |
|   }
 | |
|   const click_handler = (e) => onClick(e);
 | |
|   const load_handler = () => {
 | |
|     $$invalidate(5, loaded = true);
 | |
|     $$invalidate(6, loading = false);
 | |
|   };
 | |
|   const error_handler = () => {
 | |
|     $$invalidate(7, failed = true);
 | |
|     $$invalidate(6, loading = false);
 | |
|   };
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("src" in $$props2)
 | |
|       $$invalidate(0, src = $$props2.src);
 | |
|     if ("alt" in $$props2)
 | |
|       $$invalidate(1, alt = $$props2.alt);
 | |
|     if ("fadeIn" in $$props2)
 | |
|       $$invalidate(2, fadeIn = $$props2.fadeIn);
 | |
|     if ("opacity" in $$props2)
 | |
|       $$invalidate(3, opacity = $$props2.opacity);
 | |
|     if ("class" in $$props2)
 | |
|       $$invalidate(4, _class = $$props2.class);
 | |
|     if ("$$scope" in $$props2)
 | |
|       $$invalidate(9, $$scope = $$props2.$$scope);
 | |
|   };
 | |
|   return [
 | |
|     src,
 | |
|     alt,
 | |
|     fadeIn,
 | |
|     opacity,
 | |
|     _class,
 | |
|     loaded,
 | |
|     loading,
 | |
|     failed,
 | |
|     onClick,
 | |
|     $$scope,
 | |
|     slots,
 | |
|     click_handler,
 | |
|     load_handler,
 | |
|     error_handler
 | |
|   ];
 | |
| }
 | |
| var Image = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance10, create_fragment10, safe_not_equal, {
 | |
|       src: 0,
 | |
|       alt: 1,
 | |
|       fadeIn: 2,
 | |
|       opacity: 3,
 | |
|       class: 4
 | |
|     }, add_css7);
 | |
|   }
 | |
| };
 | |
| var Image_default = Image;
 | |
| 
 | |
| // src/ui/PodcastView/PodcastGridCard.svelte
 | |
| function add_css8(target) {
 | |
|   append_styles(target, "svelte-13t4swo", ".podcast-image{width:100%;height:100%;cursor:pointer !important;object-fit:cover;background-size:cover;background-position:center;background-repeat:no-repeat;border:1px solid var(--background-modifier-border)}");
 | |
| }
 | |
| function create_fragment11(ctx) {
 | |
|   let image;
 | |
|   let current;
 | |
|   image = new Image_default({
 | |
|     props: {
 | |
|       src: ctx[0].artworkUrl,
 | |
|       alt: ctx[0].title,
 | |
|       class: "podcast-image"
 | |
|     }
 | |
|   });
 | |
|   image.$on("click", function() {
 | |
|     if (is_function(ctx[1].bind(null, ctx[0])))
 | |
|       ctx[1].bind(null, ctx[0]).apply(this, arguments);
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(image.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(image, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(new_ctx, [dirty]) {
 | |
|       ctx = new_ctx;
 | |
|       const image_changes = {};
 | |
|       if (dirty & 1)
 | |
|         image_changes.src = ctx[0].artworkUrl;
 | |
|       if (dirty & 1)
 | |
|         image_changes.alt = ctx[0].title;
 | |
|       image.$set(image_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(image.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(image.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(image, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance11($$self, $$props, $$invalidate) {
 | |
|   let { feed } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function onclickPodcast(feed2) {
 | |
|     dispatch2("clickPodcast", { feed: feed2 });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("feed" in $$props2)
 | |
|       $$invalidate(0, feed = $$props2.feed);
 | |
|   };
 | |
|   return [feed, onclickPodcast];
 | |
| }
 | |
| var PodcastGridCard = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance11, create_fragment11, safe_not_equal, { feed: 0 }, add_css8);
 | |
|   }
 | |
| };
 | |
| var PodcastGridCard_default = PodcastGridCard;
 | |
| 
 | |
| // src/ui/PodcastView/PodcastGrid.svelte
 | |
| function add_css9(target) {
 | |
|   append_styles(target, "svelte-1xbcyvn", ".podcast-grid.svelte-1xbcyvn{display:grid;grid-template-columns:repeat(auto-fit, minmax(7rem, 1fr));grid-auto-flow:row;grid-auto-rows:1fr;grid-gap:0rem}");
 | |
| }
 | |
| function get_each_context3(ctx, list, i) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   child_ctx[5] = list[i];
 | |
|   return child_ctx;
 | |
| }
 | |
| function get_each_context_1(ctx, list, i) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   child_ctx[8] = list[i];
 | |
|   return child_ctx;
 | |
| }
 | |
| function create_if_block_12(ctx) {
 | |
|   let each_1_anchor;
 | |
|   let current;
 | |
|   let each_value_1 = ctx[1];
 | |
|   let each_blocks = [];
 | |
|   for (let i = 0; i < each_value_1.length; i += 1) {
 | |
|     each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i));
 | |
|   }
 | |
|   const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
 | |
|     each_blocks[i] = null;
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].c();
 | |
|       }
 | |
|       each_1_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].m(target, anchor);
 | |
|       }
 | |
|       insert(target, each_1_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (dirty & 6) {
 | |
|         each_value_1 = ctx2[1];
 | |
|         let i;
 | |
|         for (i = 0; i < each_value_1.length; i += 1) {
 | |
|           const child_ctx = get_each_context_1(ctx2, each_value_1, i);
 | |
|           if (each_blocks[i]) {
 | |
|             each_blocks[i].p(child_ctx, dirty);
 | |
|             transition_in(each_blocks[i], 1);
 | |
|           } else {
 | |
|             each_blocks[i] = create_each_block_1(child_ctx);
 | |
|             each_blocks[i].c();
 | |
|             transition_in(each_blocks[i], 1);
 | |
|             each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
 | |
|           }
 | |
|         }
 | |
|         group_outros();
 | |
|         for (i = each_value_1.length; i < each_blocks.length; i += 1) {
 | |
|           out(i);
 | |
|         }
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       for (let i = 0; i < each_value_1.length; i += 1) {
 | |
|         transition_in(each_blocks[i]);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       each_blocks = each_blocks.filter(Boolean);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         transition_out(each_blocks[i]);
 | |
|       }
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_each(each_blocks, detaching);
 | |
|       if (detaching)
 | |
|         detach(each_1_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_each_block_1(ctx) {
 | |
|   let playlistcard;
 | |
|   let current;
 | |
|   playlistcard = new PlaylistCard_default({ props: { playlist: ctx[8] } });
 | |
|   playlistcard.$on("clickPlaylist", ctx[2]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(playlistcard.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(playlistcard, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const playlistcard_changes = {};
 | |
|       if (dirty & 2)
 | |
|         playlistcard_changes.playlist = ctx2[8];
 | |
|       playlistcard.$set(playlistcard_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(playlistcard.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(playlistcard.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(playlistcard, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_else_block2(ctx) {
 | |
|   let div;
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       div.innerHTML = `<p>No saved podcasts.</p>`;
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block4(ctx) {
 | |
|   let each_1_anchor;
 | |
|   let current;
 | |
|   let each_value = ctx[0];
 | |
|   let each_blocks = [];
 | |
|   for (let i = 0; i < each_value.length; i += 1) {
 | |
|     each_blocks[i] = create_each_block3(get_each_context3(ctx, each_value, i));
 | |
|   }
 | |
|   const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
 | |
|     each_blocks[i] = null;
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].c();
 | |
|       }
 | |
|       each_1_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].m(target, anchor);
 | |
|       }
 | |
|       insert(target, each_1_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (dirty & 1) {
 | |
|         each_value = ctx2[0];
 | |
|         let i;
 | |
|         for (i = 0; i < each_value.length; i += 1) {
 | |
|           const child_ctx = get_each_context3(ctx2, each_value, i);
 | |
|           if (each_blocks[i]) {
 | |
|             each_blocks[i].p(child_ctx, dirty);
 | |
|             transition_in(each_blocks[i], 1);
 | |
|           } else {
 | |
|             each_blocks[i] = create_each_block3(child_ctx);
 | |
|             each_blocks[i].c();
 | |
|             transition_in(each_blocks[i], 1);
 | |
|             each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
 | |
|           }
 | |
|         }
 | |
|         group_outros();
 | |
|         for (i = each_value.length; i < each_blocks.length; i += 1) {
 | |
|           out(i);
 | |
|         }
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       for (let i = 0; i < each_value.length; i += 1) {
 | |
|         transition_in(each_blocks[i]);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       each_blocks = each_blocks.filter(Boolean);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         transition_out(each_blocks[i]);
 | |
|       }
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_each(each_blocks, detaching);
 | |
|       if (detaching)
 | |
|         detach(each_1_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_each_block3(ctx) {
 | |
|   let podcastgridcard;
 | |
|   let current;
 | |
|   podcastgridcard = new PodcastGridCard_default({ props: { feed: ctx[5] } });
 | |
|   podcastgridcard.$on("clickPodcast", ctx[3]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(podcastgridcard.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(podcastgridcard, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const podcastgridcard_changes = {};
 | |
|       if (dirty & 1)
 | |
|         podcastgridcard_changes.feed = ctx2[5];
 | |
|       podcastgridcard.$set(podcastgridcard_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(podcastgridcard.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(podcastgridcard.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(podcastgridcard, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment12(ctx) {
 | |
|   let div;
 | |
|   let t;
 | |
|   let current_block_type_index;
 | |
|   let if_block1;
 | |
|   let current;
 | |
|   let if_block0 = ctx[1].length > 0 && create_if_block_12(ctx);
 | |
|   const if_block_creators = [create_if_block4, create_else_block2];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[0].length > 0)
 | |
|       return 0;
 | |
|     return 1;
 | |
|   }
 | |
|   current_block_type_index = select_block_type(ctx, -1);
 | |
|   if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       if (if_block0)
 | |
|         if_block0.c();
 | |
|       t = space();
 | |
|       if_block1.c();
 | |
|       attr(div, "class", "podcast-grid svelte-1xbcyvn");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       if (if_block0)
 | |
|         if_block0.m(div, null);
 | |
|       append(div, t);
 | |
|       if_blocks[current_block_type_index].m(div, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (ctx2[1].length > 0) {
 | |
|         if (if_block0) {
 | |
|           if_block0.p(ctx2, dirty);
 | |
|           if (dirty & 2) {
 | |
|             transition_in(if_block0, 1);
 | |
|           }
 | |
|         } else {
 | |
|           if_block0 = create_if_block_12(ctx2);
 | |
|           if_block0.c();
 | |
|           transition_in(if_block0, 1);
 | |
|           if_block0.m(div, t);
 | |
|         }
 | |
|       } else if (if_block0) {
 | |
|         group_outros();
 | |
|         transition_out(if_block0, 1, 1, () => {
 | |
|           if_block0 = null;
 | |
|         });
 | |
|         check_outros();
 | |
|       }
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|       } else {
 | |
|         group_outros();
 | |
|         transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|           if_blocks[previous_block_index] = null;
 | |
|         });
 | |
|         check_outros();
 | |
|         if_block1 = if_blocks[current_block_type_index];
 | |
|         if (!if_block1) {
 | |
|           if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|           if_block1.c();
 | |
|         } else {
 | |
|           if_block1.p(ctx2, dirty);
 | |
|         }
 | |
|         transition_in(if_block1, 1);
 | |
|         if_block1.m(div, null);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block0);
 | |
|       transition_in(if_block1);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block0);
 | |
|       transition_out(if_block1);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       if (if_block0)
 | |
|         if_block0.d();
 | |
|       if_blocks[current_block_type_index].d();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance12($$self, $$props, $$invalidate) {
 | |
|   let { feeds = [] } = $$props;
 | |
|   let { playlists: playlists2 = [] } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function forwardClickPlaylist({ detail: { playlist, event } }) {
 | |
|     dispatch2("clickPlaylist", { playlist, event });
 | |
|   }
 | |
|   function clickPodcast_handler(event) {
 | |
|     bubble.call(this, $$self, event);
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("feeds" in $$props2)
 | |
|       $$invalidate(0, feeds = $$props2.feeds);
 | |
|     if ("playlists" in $$props2)
 | |
|       $$invalidate(1, playlists2 = $$props2.playlists);
 | |
|   };
 | |
|   return [feeds, playlists2, forwardClickPlaylist, clickPodcast_handler];
 | |
| }
 | |
| var PodcastGrid = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance12, create_fragment12, safe_not_equal, { feeds: 0, playlists: 1 }, add_css9);
 | |
|   }
 | |
| };
 | |
| var PodcastGrid_default = PodcastGrid;
 | |
| 
 | |
| // src/ui/obsidian/Slider.svelte
 | |
| var import_obsidian13 = require("obsidian");
 | |
| function create_fragment13(ctx) {
 | |
|   let span;
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       ctx[4](span);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       ctx[4](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance13($$self, $$props, $$invalidate) {
 | |
|   let { value } = $$props;
 | |
|   let { limits } = $$props;
 | |
|   let sliderRef;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   let slider;
 | |
|   let { style: styles } = $$props;
 | |
|   onMount(() => {
 | |
|     slider = new import_obsidian13.SliderComponent(sliderRef);
 | |
|     updateSliderAttributes(slider);
 | |
|   });
 | |
|   afterUpdate(() => {
 | |
|     updateSliderAttributes(slider);
 | |
|   });
 | |
|   function updateSliderAttributes(sldr) {
 | |
|     if (value)
 | |
|       sldr.setValue(value);
 | |
|     if (limits)
 | |
|       sldr.setLimits.apply(sldr, limits);
 | |
|     if (styles) {
 | |
|       sldr.sliderEl.setAttr("style", extractStylesFromObj(styles));
 | |
|     }
 | |
|     sldr.onChange((value2) => {
 | |
|       dispatch2("change", { value: value2 });
 | |
|     });
 | |
|   }
 | |
|   function span_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       sliderRef = $$value;
 | |
|       $$invalidate(0, sliderRef);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("value" in $$props2)
 | |
|       $$invalidate(1, value = $$props2.value);
 | |
|     if ("limits" in $$props2)
 | |
|       $$invalidate(2, limits = $$props2.limits);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(3, styles = $$props2.style);
 | |
|   };
 | |
|   return [sliderRef, value, limits, styles, span_binding];
 | |
| }
 | |
| var Slider = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance13, create_fragment13, safe_not_equal, { value: 1, limits: 2, style: 3 });
 | |
|   }
 | |
| };
 | |
| var Slider_default = Slider;
 | |
| 
 | |
| // src/ui/PodcastView/Loading.svelte
 | |
| function add_css10(target) {
 | |
|   append_styles(target, "svelte-11b4xh2", ".la-line-scale.svelte-11b4xh2.svelte-11b4xh2,.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.la-line-scale.svelte-11b4xh2.svelte-11b4xh2{display:block;font-size:0;color:#fff}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor}.la-line-scale.svelte-11b4xh2.svelte-11b4xh2{width:40px;height:32px}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{width:4px;height:32px;margin:2px;margin-top:0;margin-bottom:0;border-radius:0;-webkit-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;-moz-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;-o-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;animation:svelte-11b4xh2-line-scale 1.2s infinite ease}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(1){-webkit-animation-delay:-1.2s;-moz-animation-delay:-1.2s;-o-animation-delay:-1.2s;animation-delay:-1.2s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(2){-webkit-animation-delay:-1.1s;-moz-animation-delay:-1.1s;-o-animation-delay:-1.1s;animation-delay:-1.1s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(3){-webkit-animation-delay:-1s;-moz-animation-delay:-1s;-o-animation-delay:-1s;animation-delay:-1s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(4){-webkit-animation-delay:-.9s;-moz-animation-delay:-.9s;-o-animation-delay:-.9s;animation-delay:-.9s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(5){-webkit-animation-delay:-.8s;-moz-animation-delay:-.8s;-o-animation-delay:-.8s;animation-delay:-.8s}@-webkit-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1)}}@-moz-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-moz-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-moz-transform:scaleY(1);transform:scaleY(1)}}@-o-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-o-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1)}}@keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-moz-transform:scaleY(.4);-o-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1)}}");
 | |
| }
 | |
| function create_fragment14(ctx) {
 | |
|   let div5;
 | |
|   return {
 | |
|     c() {
 | |
|       div5 = element("div");
 | |
|       div5.innerHTML = `<div class="svelte-11b4xh2"></div> 
 | |
| 	<div class="svelte-11b4xh2"></div> 
 | |
| 	<div class="svelte-11b4xh2"></div> 
 | |
| 	<div class="svelte-11b4xh2"></div> 
 | |
| 	<div class="svelte-11b4xh2"></div>`;
 | |
|       attr(div5, "class", "la-line-scale svelte-11b4xh2");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div5, anchor);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div5);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| var Loading = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, null, create_fragment14, safe_not_equal, {}, add_css10);
 | |
|   }
 | |
| };
 | |
| var Loading_default = Loading;
 | |
| 
 | |
| // src/ui/common/IntersectionObserver.svelte
 | |
| function add_css11(target) {
 | |
|   append_styles(target, "svelte-1kuj9kb", "div.svelte-1kuj9kb{width:100%;height:100%}");
 | |
| }
 | |
| var get_default_slot_changes = (dirty) => ({ intersecting: dirty & 1 });
 | |
| var get_default_slot_context = (ctx) => ({ intersecting: ctx[0] });
 | |
| function create_fragment15(ctx) {
 | |
|   let div;
 | |
|   let current;
 | |
|   const default_slot_template = ctx[8].default;
 | |
|   const default_slot = create_slot(default_slot_template, ctx, ctx[7], get_default_slot_context);
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       if (default_slot)
 | |
|         default_slot.c();
 | |
|       attr(div, "class", "svelte-1kuj9kb");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       if (default_slot) {
 | |
|         default_slot.m(div, null);
 | |
|       }
 | |
|       ctx[9](div);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (default_slot) {
 | |
|         if (default_slot.p && (!current || dirty & 129)) {
 | |
|           update_slot_base(default_slot, default_slot_template, ctx2, ctx2[7], !current ? get_all_dirty_from_scope(ctx2[7]) : get_slot_changes(default_slot_template, ctx2[7], dirty, get_default_slot_changes), get_default_slot_context);
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(default_slot, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(default_slot, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       if (default_slot)
 | |
|         default_slot.d(detaching);
 | |
|       ctx[9](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance14($$self, $$props, $$invalidate) {
 | |
|   let { $$slots: slots = {}, $$scope } = $$props;
 | |
|   let { once = false } = $$props;
 | |
|   let { top = 0 } = $$props;
 | |
|   let { bottom = 0 } = $$props;
 | |
|   let { left = 0 } = $$props;
 | |
|   let { right = 0 } = $$props;
 | |
|   let intersecting = false;
 | |
|   let container;
 | |
|   onMount(() => {
 | |
|     if (typeof IntersectionObserver !== "undefined") {
 | |
|       const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`;
 | |
|       const observer = new IntersectionObserver((entries) => {
 | |
|         $$invalidate(0, intersecting = entries[0].isIntersecting);
 | |
|         if (intersecting && once) {
 | |
|           observer.unobserve(container);
 | |
|         }
 | |
|       }, { rootMargin });
 | |
|       observer.observe(container);
 | |
|       return () => observer.unobserve(container);
 | |
|     }
 | |
|     function handler() {
 | |
|       const bcr = container.getBoundingClientRect();
 | |
|       $$invalidate(0, intersecting = bcr.bottom + bottom > 0 && bcr.right + right > 0 && bcr.top - top < window.innerHeight && bcr.left - left < window.innerWidth);
 | |
|       if (intersecting && once) {
 | |
|         window.removeEventListener("scroll", handler);
 | |
|       }
 | |
|     }
 | |
|     window.addEventListener("scroll", handler);
 | |
|     return () => window.removeEventListener("scroll", handler);
 | |
|   });
 | |
|   function div_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       container = $$value;
 | |
|       $$invalidate(1, container);
 | |
|     });
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("once" in $$props2)
 | |
|       $$invalidate(2, once = $$props2.once);
 | |
|     if ("top" in $$props2)
 | |
|       $$invalidate(3, top = $$props2.top);
 | |
|     if ("bottom" in $$props2)
 | |
|       $$invalidate(4, bottom = $$props2.bottom);
 | |
|     if ("left" in $$props2)
 | |
|       $$invalidate(5, left = $$props2.left);
 | |
|     if ("right" in $$props2)
 | |
|       $$invalidate(6, right = $$props2.right);
 | |
|     if ("$$scope" in $$props2)
 | |
|       $$invalidate(7, $$scope = $$props2.$$scope);
 | |
|   };
 | |
|   return [
 | |
|     intersecting,
 | |
|     container,
 | |
|     once,
 | |
|     top,
 | |
|     bottom,
 | |
|     left,
 | |
|     right,
 | |
|     $$scope,
 | |
|     slots,
 | |
|     div_binding
 | |
|   ];
 | |
| }
 | |
| var IntersectionObserver_1 = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance14, create_fragment15, safe_not_equal, {
 | |
|       once: 2,
 | |
|       top: 3,
 | |
|       bottom: 4,
 | |
|       left: 5,
 | |
|       right: 6
 | |
|     }, add_css11);
 | |
|   }
 | |
| };
 | |
| var IntersectionObserver_default = IntersectionObserver_1;
 | |
| 
 | |
| // src/ui/common/ImageLoader.svelte
 | |
| function create_if_block5(ctx) {
 | |
|   let image;
 | |
|   let current;
 | |
|   image = new Image_default({
 | |
|     props: {
 | |
|       alt: ctx[1],
 | |
|       src: ctx[0],
 | |
|       fadeIn: ctx[2],
 | |
|       class: ctx[3]
 | |
|     }
 | |
|   });
 | |
|   image.$on("click", ctx[5]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(image.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(image, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const image_changes = {};
 | |
|       if (dirty & 2)
 | |
|         image_changes.alt = ctx2[1];
 | |
|       if (dirty & 1)
 | |
|         image_changes.src = ctx2[0];
 | |
|       if (dirty & 4)
 | |
|         image_changes.fadeIn = ctx2[2];
 | |
|       if (dirty & 8)
 | |
|         image_changes.class = ctx2[3];
 | |
|       image.$set(image_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(image.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(image.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(image, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_default_slot(ctx) {
 | |
|   let if_block_anchor;
 | |
|   let current;
 | |
|   let if_block = ctx[6] && create_if_block5(ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       if_block_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       if (if_block)
 | |
|         if_block.m(target, anchor);
 | |
|       insert(target, if_block_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (ctx2[6]) {
 | |
|         if (if_block) {
 | |
|           if_block.p(ctx2, dirty);
 | |
|           if (dirty & 64) {
 | |
|             transition_in(if_block, 1);
 | |
|           }
 | |
|         } else {
 | |
|           if_block = create_if_block5(ctx2);
 | |
|           if_block.c();
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(if_block_anchor.parentNode, if_block_anchor);
 | |
|         }
 | |
|       } else if (if_block) {
 | |
|         group_outros();
 | |
|         transition_out(if_block, 1, 1, () => {
 | |
|           if_block = null;
 | |
|         });
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (if_block)
 | |
|         if_block.d(detaching);
 | |
|       if (detaching)
 | |
|         detach(if_block_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment16(ctx) {
 | |
|   let intersectionobserver;
 | |
|   let current;
 | |
|   intersectionobserver = new IntersectionObserver_default({
 | |
|     props: {
 | |
|       once: true,
 | |
|       $$slots: {
 | |
|         default: [
 | |
|           create_default_slot,
 | |
|           ({ intersecting }) => ({ 6: intersecting }),
 | |
|           ({ intersecting }) => intersecting ? 64 : 0
 | |
|         ]
 | |
|       },
 | |
|       $$scope: { ctx }
 | |
|     }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(intersectionobserver.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(intersectionobserver, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const intersectionobserver_changes = {};
 | |
|       if (dirty & 207) {
 | |
|         intersectionobserver_changes.$$scope = { dirty, ctx: ctx2 };
 | |
|       }
 | |
|       intersectionobserver.$set(intersectionobserver_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(intersectionobserver.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(intersectionobserver.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(intersectionobserver, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance15($$self, $$props, $$invalidate) {
 | |
|   let { src } = $$props;
 | |
|   let { alt } = $$props;
 | |
|   let { fadeIn = false } = $$props;
 | |
|   let { class: _class = "" } = $$props;
 | |
|   const dispatcher = createEventDispatcher();
 | |
|   const click_handler = (event) => dispatcher("click", { event });
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("src" in $$props2)
 | |
|       $$invalidate(0, src = $$props2.src);
 | |
|     if ("alt" in $$props2)
 | |
|       $$invalidate(1, alt = $$props2.alt);
 | |
|     if ("fadeIn" in $$props2)
 | |
|       $$invalidate(2, fadeIn = $$props2.fadeIn);
 | |
|     if ("class" in $$props2)
 | |
|       $$invalidate(3, _class = $$props2.class);
 | |
|   };
 | |
|   return [src, alt, fadeIn, _class, dispatcher, click_handler];
 | |
| }
 | |
| var ImageLoader = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance15, create_fragment16, safe_not_equal, { src: 0, alt: 1, fadeIn: 2, class: 3 });
 | |
|   }
 | |
| };
 | |
| var ImageLoader_default = ImageLoader;
 | |
| 
 | |
| // src/ui/PodcastView/EpisodeListItem.svelte
 | |
| function add_css12(target) {
 | |
|   append_styles(target, "svelte-1gcgk6w", ".podcast-episode-item.svelte-1gcgk6w{display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding:0.5rem;width:100%;border:solid 1px var(--background-divider);gap:0.25rem}.podcast-episode-item.svelte-1gcgk6w:hover{background-color:var(--background-divider)}.podcast-episode-item.svelte-1gcgk6w:hover{cursor:pointer}.strikeout.svelte-1gcgk6w{text-decoration:line-through}.podcast-episode-information.svelte-1gcgk6w{display:flex;flex-direction:column;justify-content:space-between;align-items:left;width:100%}.episode-item-date.svelte-1gcgk6w{color:gray}.podcast-episode-thumbnail-container.svelte-1gcgk6w{flex-basis:20%;display:flex;align-items:center;justify-content:center}.podcast-episode-thumbnail{border-radius:15%;max-width:5rem;max-height:5rem;cursor:pointer !important}");
 | |
| }
 | |
| function create_if_block_13(ctx) {
 | |
|   let div;
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       attr(div, "class", "podcast-episode-thumbnail-container svelte-1gcgk6w");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|     },
 | |
|     p: noop,
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block6(ctx) {
 | |
|   let div;
 | |
|   let imageloader;
 | |
|   let current;
 | |
|   imageloader = new ImageLoader_default({
 | |
|     props: {
 | |
|       src: ctx[0].artworkUrl,
 | |
|       alt: ctx[0].title,
 | |
|       fadeIn: true,
 | |
|       class: "podcast-episode-thumbnail"
 | |
|     }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(imageloader.$$.fragment);
 | |
|       attr(div, "class", "podcast-episode-thumbnail-container svelte-1gcgk6w");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(imageloader, div, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const imageloader_changes = {};
 | |
|       if (dirty & 1)
 | |
|         imageloader_changes.src = ctx2[0].artworkUrl;
 | |
|       if (dirty & 1)
 | |
|         imageloader_changes.alt = ctx2[0].title;
 | |
|       imageloader.$set(imageloader_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(imageloader.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(imageloader.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(imageloader);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment17(ctx) {
 | |
|   let div1;
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let t0;
 | |
|   let div0;
 | |
|   let span0;
 | |
|   let t1_value = ctx[3].toUpperCase() + "";
 | |
|   let t1;
 | |
|   let t2;
 | |
|   let span1;
 | |
|   let t3_value = ctx[0].title + "";
 | |
|   let t3;
 | |
|   let span1_class_value;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   const if_block_creators = [create_if_block6, create_if_block_13];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[2] && ctx2[0]?.artworkUrl)
 | |
|       return 0;
 | |
|     if (ctx2[2])
 | |
|       return 1;
 | |
|     return -1;
 | |
|   }
 | |
|   if (~(current_block_type_index = select_block_type(ctx, -1))) {
 | |
|     if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   }
 | |
|   return {
 | |
|     c() {
 | |
|       div1 = element("div");
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       t0 = space();
 | |
|       div0 = element("div");
 | |
|       span0 = element("span");
 | |
|       t1 = text(t1_value);
 | |
|       t2 = space();
 | |
|       span1 = element("span");
 | |
|       t3 = text(t3_value);
 | |
|       attr(span0, "class", "episode-item-date svelte-1gcgk6w");
 | |
|       attr(span1, "class", span1_class_value = null_to_empty(`episode-item-title ${ctx[1] && "strikeout"}`) + " svelte-1gcgk6w");
 | |
|       attr(div0, "class", "podcast-episode-information svelte-1gcgk6w");
 | |
|       set_style(div0, "flex-basis", "80%", false);
 | |
|       attr(div1, "class", "podcast-episode-item svelte-1gcgk6w");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div1, anchor);
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].m(div1, null);
 | |
|       }
 | |
|       append(div1, t0);
 | |
|       append(div1, div0);
 | |
|       append(div0, span0);
 | |
|       append(span0, t1);
 | |
|       append(div0, t2);
 | |
|       append(div0, span1);
 | |
|       append(span1, t3);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(div1, "click", ctx[4]),
 | |
|           listen(div1, "contextmenu", ctx[5])
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if (~current_block_type_index) {
 | |
|           if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|         }
 | |
|       } else {
 | |
|         if (if_block) {
 | |
|           group_outros();
 | |
|           transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|             if_blocks[previous_block_index] = null;
 | |
|           });
 | |
|           check_outros();
 | |
|         }
 | |
|         if (~current_block_type_index) {
 | |
|           if_block = if_blocks[current_block_type_index];
 | |
|           if (!if_block) {
 | |
|             if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|             if_block.c();
 | |
|           } else {
 | |
|             if_block.p(ctx2, dirty);
 | |
|           }
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(div1, t0);
 | |
|         } else {
 | |
|           if_block = null;
 | |
|         }
 | |
|       }
 | |
|       if ((!current || dirty & 8) && t1_value !== (t1_value = ctx2[3].toUpperCase() + ""))
 | |
|         set_data(t1, t1_value);
 | |
|       if ((!current || dirty & 1) && t3_value !== (t3_value = ctx2[0].title + ""))
 | |
|         set_data(t3, t3_value);
 | |
|       if (!current || dirty & 2 && span1_class_value !== (span1_class_value = null_to_empty(`episode-item-title ${ctx2[1] && "strikeout"}`) + " svelte-1gcgk6w")) {
 | |
|         attr(span1, "class", span1_class_value);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div1);
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].d();
 | |
|       }
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance16($$self, $$props, $$invalidate) {
 | |
|   let { episode } = $$props;
 | |
|   let { episodeFinished = false } = $$props;
 | |
|   let { showEpisodeImage = false } = $$props;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function onClickEpisode() {
 | |
|     dispatch2("clickEpisode", { episode });
 | |
|   }
 | |
|   function onContextMenu(event) {
 | |
|     dispatch2("contextMenu", { episode, event });
 | |
|   }
 | |
|   let _date;
 | |
|   let date;
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("episode" in $$props2)
 | |
|       $$invalidate(0, episode = $$props2.episode);
 | |
|     if ("episodeFinished" in $$props2)
 | |
|       $$invalidate(1, episodeFinished = $$props2.episodeFinished);
 | |
|     if ("showEpisodeImage" in $$props2)
 | |
|       $$invalidate(2, showEpisodeImage = $$props2.showEpisodeImage);
 | |
|   };
 | |
|   $$self.$$.update = () => {
 | |
|     if ($$self.$$.dirty & 65) {
 | |
|       $: {
 | |
|         $$invalidate(6, _date = new Date(episode.episodeDate || ""));
 | |
|         $$invalidate(3, date = window.moment(_date).format("DD MMMM YYYY"));
 | |
|       }
 | |
|     }
 | |
|   };
 | |
|   return [
 | |
|     episode,
 | |
|     episodeFinished,
 | |
|     showEpisodeImage,
 | |
|     date,
 | |
|     onClickEpisode,
 | |
|     onContextMenu,
 | |
|     _date
 | |
|   ];
 | |
| }
 | |
| var EpisodeListItem = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance16, create_fragment17, safe_not_equal, {
 | |
|       episode: 0,
 | |
|       episodeFinished: 1,
 | |
|       showEpisodeImage: 2
 | |
|     }, add_css12);
 | |
|   }
 | |
| };
 | |
| var EpisodeListItem_default = EpisodeListItem;
 | |
| 
 | |
| // src/ui/PodcastView/EpisodeList.svelte
 | |
| function add_css13(target) {
 | |
|   append_styles(target, "svelte-1ov6u04", ".episode-list-view-container.svelte-1ov6u04{display:flex;flex-direction:column;align-items:center;justify-content:center}.podcast-episode-list.svelte-1ov6u04{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%}.episode-list-menu.svelte-1ov6u04{display:flex;flex-direction:row;justify-content:right;align-items:center;gap:1rem;width:100%;padding-left:0.5rem;padding-right:0.5rem}.episode-list-search.svelte-1ov6u04{width:100%;margin-bottom:0.5rem}");
 | |
| }
 | |
| function get_each_context4(ctx, list, i) {
 | |
|   const child_ctx = ctx.slice();
 | |
|   child_ctx[15] = list[i];
 | |
|   const constants_0 = child_ctx[5][child_ctx[15].title]?.finished;
 | |
|   child_ctx[16] = constants_0;
 | |
|   return child_ctx;
 | |
| }
 | |
| var get_header_slot_changes = (dirty) => ({});
 | |
| var get_header_slot_context = (ctx) => ({});
 | |
| function fallback_block(ctx) {
 | |
|   let t;
 | |
|   return {
 | |
|     c() {
 | |
|       t = text("Fallback");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, t, anchor);
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(t);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block_2(ctx) {
 | |
|   let div1;
 | |
|   let div0;
 | |
|   let text_1;
 | |
|   let updating_value;
 | |
|   let t0;
 | |
|   let icon0;
 | |
|   let t1;
 | |
|   let icon1;
 | |
|   let current;
 | |
|   function text_1_value_binding(value) {
 | |
|     ctx[12](value);
 | |
|   }
 | |
|   let text_1_props = {
 | |
|     placeholder: "Search episodes",
 | |
|     style: { width: "100%" }
 | |
|   };
 | |
|   if (ctx[4] !== void 0) {
 | |
|     text_1_props.value = ctx[4];
 | |
|   }
 | |
|   text_1 = new Text_default({ props: text_1_props });
 | |
|   binding_callbacks.push(() => bind(text_1, "value", text_1_value_binding));
 | |
|   text_1.$on("change", ctx[9]);
 | |
|   icon0 = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[3] ? "eye-off" : "eye",
 | |
|       size: 25
 | |
|     }
 | |
|   });
 | |
|   icon0.$on("click", ctx[13]);
 | |
|   icon1 = new Icon_default({ props: { icon: "refresh-cw", size: 25 } });
 | |
|   icon1.$on("click", ctx[14]);
 | |
|   return {
 | |
|     c() {
 | |
|       div1 = element("div");
 | |
|       div0 = element("div");
 | |
|       create_component(text_1.$$.fragment);
 | |
|       t0 = space();
 | |
|       create_component(icon0.$$.fragment);
 | |
|       t1 = space();
 | |
|       create_component(icon1.$$.fragment);
 | |
|       attr(div0, "class", "episode-list-search svelte-1ov6u04");
 | |
|       attr(div1, "class", "episode-list-menu svelte-1ov6u04");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div1, anchor);
 | |
|       append(div1, div0);
 | |
|       mount_component(text_1, div0, null);
 | |
|       append(div1, t0);
 | |
|       mount_component(icon0, div1, null);
 | |
|       append(div1, t1);
 | |
|       mount_component(icon1, div1, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const text_1_changes = {};
 | |
|       if (!updating_value && dirty & 16) {
 | |
|         updating_value = true;
 | |
|         text_1_changes.value = ctx2[4];
 | |
|         add_flush_callback(() => updating_value = false);
 | |
|       }
 | |
|       text_1.$set(text_1_changes);
 | |
|       const icon0_changes = {};
 | |
|       if (dirty & 8)
 | |
|         icon0_changes.icon = ctx2[3] ? "eye-off" : "eye";
 | |
|       icon0.$set(icon0_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(text_1.$$.fragment, local);
 | |
|       transition_in(icon0.$$.fragment, local);
 | |
|       transition_in(icon1.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(text_1.$$.fragment, local);
 | |
|       transition_out(icon0.$$.fragment, local);
 | |
|       transition_out(icon1.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div1);
 | |
|       destroy_component(text_1);
 | |
|       destroy_component(icon0);
 | |
|       destroy_component(icon1);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block_14(ctx) {
 | |
|   let p;
 | |
|   return {
 | |
|     c() {
 | |
|       p = element("p");
 | |
|       p.textContent = "No episodes found.";
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, p, anchor);
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(p);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block7(ctx) {
 | |
|   let episodelistitem;
 | |
|   let current;
 | |
|   episodelistitem = new EpisodeListItem_default({
 | |
|     props: {
 | |
|       episode: ctx[15],
 | |
|       episodeFinished: ctx[16],
 | |
|       showEpisodeImage: ctx[1]
 | |
|     }
 | |
|   });
 | |
|   episodelistitem.$on("clickEpisode", ctx[7]);
 | |
|   episodelistitem.$on("contextMenu", ctx[8]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(episodelistitem.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(episodelistitem, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const episodelistitem_changes = {};
 | |
|       if (dirty & 1)
 | |
|         episodelistitem_changes.episode = ctx2[15];
 | |
|       if (dirty & 33)
 | |
|         episodelistitem_changes.episodeFinished = ctx2[16];
 | |
|       if (dirty & 2)
 | |
|         episodelistitem_changes.showEpisodeImage = ctx2[1];
 | |
|       episodelistitem.$set(episodelistitem_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(episodelistitem.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(episodelistitem.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(episodelistitem, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_each_block4(ctx) {
 | |
|   let if_block_anchor;
 | |
|   let current;
 | |
|   let if_block = (!ctx[3] || !ctx[16]) && create_if_block7(ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       if_block_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       if (if_block)
 | |
|         if_block.m(target, anchor);
 | |
|       insert(target, if_block_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (!ctx2[3] || !ctx2[16]) {
 | |
|         if (if_block) {
 | |
|           if_block.p(ctx2, dirty);
 | |
|           if (dirty & 41) {
 | |
|             transition_in(if_block, 1);
 | |
|           }
 | |
|         } else {
 | |
|           if_block = create_if_block7(ctx2);
 | |
|           if_block.c();
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(if_block_anchor.parentNode, if_block_anchor);
 | |
|         }
 | |
|       } else if (if_block) {
 | |
|         group_outros();
 | |
|         transition_out(if_block, 1, 1, () => {
 | |
|           if_block = null;
 | |
|         });
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (if_block)
 | |
|         if_block.d(detaching);
 | |
|       if (detaching)
 | |
|         detach(if_block_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment18(ctx) {
 | |
|   let div1;
 | |
|   let t0;
 | |
|   let t1;
 | |
|   let div0;
 | |
|   let t2;
 | |
|   let current;
 | |
|   const header_slot_template = ctx[11].header;
 | |
|   const header_slot = create_slot(header_slot_template, ctx, ctx[10], get_header_slot_context);
 | |
|   const header_slot_or_fallback = header_slot || fallback_block(ctx);
 | |
|   let if_block0 = ctx[2] && create_if_block_2(ctx);
 | |
|   let if_block1 = ctx[0].length === 0 && create_if_block_14(ctx);
 | |
|   let each_value = ctx[0];
 | |
|   let each_blocks = [];
 | |
|   for (let i = 0; i < each_value.length; i += 1) {
 | |
|     each_blocks[i] = create_each_block4(get_each_context4(ctx, each_value, i));
 | |
|   }
 | |
|   const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
 | |
|     each_blocks[i] = null;
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       div1 = element("div");
 | |
|       if (header_slot_or_fallback)
 | |
|         header_slot_or_fallback.c();
 | |
|       t0 = space();
 | |
|       if (if_block0)
 | |
|         if_block0.c();
 | |
|       t1 = space();
 | |
|       div0 = element("div");
 | |
|       if (if_block1)
 | |
|         if_block1.c();
 | |
|       t2 = space();
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].c();
 | |
|       }
 | |
|       attr(div0, "class", "podcast-episode-list svelte-1ov6u04");
 | |
|       attr(div1, "class", "episode-list-view-container svelte-1ov6u04");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div1, anchor);
 | |
|       if (header_slot_or_fallback) {
 | |
|         header_slot_or_fallback.m(div1, null);
 | |
|       }
 | |
|       append(div1, t0);
 | |
|       if (if_block0)
 | |
|         if_block0.m(div1, null);
 | |
|       append(div1, t1);
 | |
|       append(div1, div0);
 | |
|       if (if_block1)
 | |
|         if_block1.m(div0, null);
 | |
|       append(div0, t2);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         each_blocks[i].m(div0, null);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (header_slot) {
 | |
|         if (header_slot.p && (!current || dirty & 1024)) {
 | |
|           update_slot_base(header_slot, header_slot_template, ctx2, ctx2[10], !current ? get_all_dirty_from_scope(ctx2[10]) : get_slot_changes(header_slot_template, ctx2[10], dirty, get_header_slot_changes), get_header_slot_context);
 | |
|         }
 | |
|       }
 | |
|       if (ctx2[2]) {
 | |
|         if (if_block0) {
 | |
|           if_block0.p(ctx2, dirty);
 | |
|           if (dirty & 4) {
 | |
|             transition_in(if_block0, 1);
 | |
|           }
 | |
|         } else {
 | |
|           if_block0 = create_if_block_2(ctx2);
 | |
|           if_block0.c();
 | |
|           transition_in(if_block0, 1);
 | |
|           if_block0.m(div1, t1);
 | |
|         }
 | |
|       } else if (if_block0) {
 | |
|         group_outros();
 | |
|         transition_out(if_block0, 1, 1, () => {
 | |
|           if_block0 = null;
 | |
|         });
 | |
|         check_outros();
 | |
|       }
 | |
|       if (ctx2[0].length === 0) {
 | |
|         if (if_block1) {
 | |
|         } else {
 | |
|           if_block1 = create_if_block_14(ctx2);
 | |
|           if_block1.c();
 | |
|           if_block1.m(div0, t2);
 | |
|         }
 | |
|       } else if (if_block1) {
 | |
|         if_block1.d(1);
 | |
|         if_block1 = null;
 | |
|       }
 | |
|       if (dirty & 427) {
 | |
|         each_value = ctx2[0];
 | |
|         let i;
 | |
|         for (i = 0; i < each_value.length; i += 1) {
 | |
|           const child_ctx = get_each_context4(ctx2, each_value, i);
 | |
|           if (each_blocks[i]) {
 | |
|             each_blocks[i].p(child_ctx, dirty);
 | |
|             transition_in(each_blocks[i], 1);
 | |
|           } else {
 | |
|             each_blocks[i] = create_each_block4(child_ctx);
 | |
|             each_blocks[i].c();
 | |
|             transition_in(each_blocks[i], 1);
 | |
|             each_blocks[i].m(div0, null);
 | |
|           }
 | |
|         }
 | |
|         group_outros();
 | |
|         for (i = each_value.length; i < each_blocks.length; i += 1) {
 | |
|           out(i);
 | |
|         }
 | |
|         check_outros();
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(header_slot_or_fallback, local);
 | |
|       transition_in(if_block0);
 | |
|       for (let i = 0; i < each_value.length; i += 1) {
 | |
|         transition_in(each_blocks[i]);
 | |
|       }
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(header_slot_or_fallback, local);
 | |
|       transition_out(if_block0);
 | |
|       each_blocks = each_blocks.filter(Boolean);
 | |
|       for (let i = 0; i < each_blocks.length; i += 1) {
 | |
|         transition_out(each_blocks[i]);
 | |
|       }
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div1);
 | |
|       if (header_slot_or_fallback)
 | |
|         header_slot_or_fallback.d(detaching);
 | |
|       if (if_block0)
 | |
|         if_block0.d();
 | |
|       if (if_block1)
 | |
|         if_block1.d();
 | |
|       destroy_each(each_blocks, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance17($$self, $$props, $$invalidate) {
 | |
|   let $playedEpisodes;
 | |
|   component_subscribe($$self, playedEpisodes, ($$value) => $$invalidate(5, $playedEpisodes = $$value));
 | |
|   let { $$slots: slots = {}, $$scope } = $$props;
 | |
|   let { episodes = [] } = $$props;
 | |
|   let { showThumbnails = false } = $$props;
 | |
|   let { showListMenu = true } = $$props;
 | |
|   let hidePlayedEpisodes = false;
 | |
|   let searchInputQuery = "";
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function forwardClickEpisode(event) {
 | |
|     dispatch2("clickEpisode", { episode: event.detail.episode });
 | |
|   }
 | |
|   function forwardContextMenuEpisode(event) {
 | |
|     dispatch2("contextMenuEpisode", {
 | |
|       episode: event.detail.episode,
 | |
|       event: event.detail.event
 | |
|     });
 | |
|   }
 | |
|   function forwardSearchInput(event) {
 | |
|     dispatch2("search", { query: event.detail.value });
 | |
|   }
 | |
|   function text_1_value_binding(value) {
 | |
|     searchInputQuery = value;
 | |
|     $$invalidate(4, searchInputQuery);
 | |
|   }
 | |
|   const click_handler = () => $$invalidate(3, hidePlayedEpisodes = !hidePlayedEpisodes);
 | |
|   const click_handler_1 = () => dispatch2("clickRefresh");
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("episodes" in $$props2)
 | |
|       $$invalidate(0, episodes = $$props2.episodes);
 | |
|     if ("showThumbnails" in $$props2)
 | |
|       $$invalidate(1, showThumbnails = $$props2.showThumbnails);
 | |
|     if ("showListMenu" in $$props2)
 | |
|       $$invalidate(2, showListMenu = $$props2.showListMenu);
 | |
|     if ("$$scope" in $$props2)
 | |
|       $$invalidate(10, $$scope = $$props2.$$scope);
 | |
|   };
 | |
|   return [
 | |
|     episodes,
 | |
|     showThumbnails,
 | |
|     showListMenu,
 | |
|     hidePlayedEpisodes,
 | |
|     searchInputQuery,
 | |
|     $playedEpisodes,
 | |
|     dispatch2,
 | |
|     forwardClickEpisode,
 | |
|     forwardContextMenuEpisode,
 | |
|     forwardSearchInput,
 | |
|     $$scope,
 | |
|     slots,
 | |
|     text_1_value_binding,
 | |
|     click_handler,
 | |
|     click_handler_1
 | |
|   ];
 | |
| }
 | |
| var EpisodeList = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance17, create_fragment18, safe_not_equal, {
 | |
|       episodes: 0,
 | |
|       showThumbnails: 1,
 | |
|       showListMenu: 2
 | |
|     }, add_css13);
 | |
|   }
 | |
| };
 | |
| var EpisodeList_default = EpisodeList;
 | |
| 
 | |
| // src/ui/common/Progressbar.svelte
 | |
| function create_fragment19(ctx) {
 | |
|   let progress;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   return {
 | |
|     c() {
 | |
|       progress = element("progress");
 | |
|       attr(progress, "style", ctx[2]);
 | |
|       attr(progress, "max", ctx[0]);
 | |
|       progress.value = ctx[1];
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, progress, anchor);
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(progress, "click", ctx[3]),
 | |
|           listen(progress, "mousedown", ctx[4]),
 | |
|           listen(progress, "mouseup", ctx[5]),
 | |
|           listen(progress, "mousemove", ctx[6])
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (dirty & 4) {
 | |
|         attr(progress, "style", ctx2[2]);
 | |
|       }
 | |
|       if (dirty & 1) {
 | |
|         attr(progress, "max", ctx2[0]);
 | |
|       }
 | |
|       if (dirty & 2) {
 | |
|         progress.value = ctx2[1];
 | |
|       }
 | |
|     },
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(progress);
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance18($$self, $$props, $$invalidate) {
 | |
|   let { max } = $$props;
 | |
|   let { value } = $$props;
 | |
|   let isDragging = false;
 | |
|   let { style: _styled = {} } = $$props;
 | |
|   let styles;
 | |
|   const dispatch2 = createEventDispatcher();
 | |
|   function forwardClick(e) {
 | |
|     dispatch2("click", { event: e });
 | |
|   }
 | |
|   function onDragStart() {
 | |
|     isDragging = true;
 | |
|   }
 | |
|   function onDragEnd() {
 | |
|     isDragging = false;
 | |
|   }
 | |
|   function handleDragging(e) {
 | |
|     if (!isDragging)
 | |
|       return;
 | |
|     forwardClick(e);
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("max" in $$props2)
 | |
|       $$invalidate(0, max = $$props2.max);
 | |
|     if ("value" in $$props2)
 | |
|       $$invalidate(1, value = $$props2.value);
 | |
|     if ("style" in $$props2)
 | |
|       $$invalidate(7, _styled = $$props2.style);
 | |
|   };
 | |
|   $$self.$$.update = () => {
 | |
|     if ($$self.$$.dirty & 128) {
 | |
|       $: {
 | |
|         $$invalidate(2, styles = extractStylesFromObj(_styled));
 | |
|       }
 | |
|     }
 | |
|   };
 | |
|   return [
 | |
|     max,
 | |
|     value,
 | |
|     styles,
 | |
|     forwardClick,
 | |
|     onDragStart,
 | |
|     onDragEnd,
 | |
|     handleDragging,
 | |
|     _styled
 | |
|   ];
 | |
| }
 | |
| var Progressbar = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance18, create_fragment19, safe_not_equal, { max: 0, value: 1, style: 7 });
 | |
|   }
 | |
| };
 | |
| var Progressbar_default = Progressbar;
 | |
| 
 | |
| // src/ui/PodcastView/spawnEpisodeContextMenu.ts
 | |
| var import_obsidian16 = require("obsidian");
 | |
| 
 | |
| // src/createPodcastNote.ts
 | |
| var import_obsidian14 = require("obsidian");
 | |
| 
 | |
| // src/utility/addExtension.ts
 | |
| function addExtension(path, extension) {
 | |
|   const ext = extension.startsWith(".") ? extension : `.${extension}`;
 | |
|   return path.endsWith(ext) ? path : `${path}${ext}`;
 | |
| }
 | |
| 
 | |
| // src/createPodcastNote.ts
 | |
| async function createPodcastNote(episode) {
 | |
|   const pluginInstance = get_store_value(plugin);
 | |
|   const filePath = FilePathTemplateEngine(pluginInstance.settings.note.path, episode);
 | |
|   const filePathDotMd = addExtension(filePath, "md");
 | |
|   const content = NoteTemplateEngine(pluginInstance.settings.note.template, episode);
 | |
|   try {
 | |
|     const file = await createFileIfNotExists(filePathDotMd, content, episode);
 | |
|     app.workspace.getLeaf().openFile(file);
 | |
|   } catch (error) {
 | |
|     console.error(error);
 | |
|     new import_obsidian14.Notice(`Failed to create note: "${filePathDotMd}"`);
 | |
|   }
 | |
| }
 | |
| function getPodcastNote(episode) {
 | |
|   const pluginInstance = get_store_value(plugin);
 | |
|   const filePath = FilePathTemplateEngine(pluginInstance.settings.note.path, episode);
 | |
|   const filePathDotMd = addExtension(filePath, "md");
 | |
|   const file = app.vault.getAbstractFileByPath(filePathDotMd);
 | |
|   if (!file || !(file instanceof import_obsidian14.TFile)) {
 | |
|     return null;
 | |
|   }
 | |
|   return file;
 | |
| }
 | |
| function openPodcastNote(epiosode) {
 | |
|   const file = getPodcastNote(epiosode);
 | |
|   if (!file) {
 | |
|     new import_obsidian14.Notice(`Note for "${epiosode.title}" does not exist`);
 | |
|     return;
 | |
|   }
 | |
|   app.workspace.getLeaf().openFile(file);
 | |
| }
 | |
| async function createFileIfNotExists(path, content, episode, createFolder = true) {
 | |
|   const file = getPodcastNote(episode);
 | |
|   if (file) {
 | |
|     new import_obsidian14.Notice(`Note for "${episode.title}" already exists`);
 | |
|     return file;
 | |
|   }
 | |
|   const foldersInPath = path.split("/").slice(0, -1);
 | |
|   for (let i = 0; i < foldersInPath.length; i++) {
 | |
|     const folderPath = foldersInPath.slice(0, i + 1).join("/");
 | |
|     const folder = app.vault.getAbstractFileByPath(folderPath);
 | |
|     if (!folder && createFolder) {
 | |
|       await app.vault.createFolder(folderPath);
 | |
|     }
 | |
|   }
 | |
|   return await app.vault.create(path, content);
 | |
| }
 | |
| 
 | |
| // src/downloadEpisode.ts
 | |
| var import_obsidian15 = require("obsidian");
 | |
| async function downloadFile(url, options) {
 | |
|   try {
 | |
|     const response = await (0, import_obsidian15.requestUrl)({ url, method: "GET" });
 | |
|     if (response.status !== 200) {
 | |
|       throw new Error("Could not download episode.");
 | |
|     }
 | |
|     const contentLength = response.arrayBuffer.byteLength;
 | |
|     options?.onFinished?.();
 | |
|     return {
 | |
|       blob: new Blob([response.arrayBuffer], {
 | |
|         type: response.headers["content-type"] ?? response.headers["Content-Type"] ?? ""
 | |
|       }),
 | |
|       contentLength,
 | |
|       receivedLength: contentLength,
 | |
|       responseUrl: url
 | |
|     };
 | |
|   } catch (error) {
 | |
|     const err = new Error(`Failed to download ${url}:
 | |
| 
 | |
| ${error.message}`);
 | |
|     options?.onError?.(err);
 | |
|     throw err;
 | |
|   }
 | |
| }
 | |
| async function downloadEpisodeWithNotice(episode, downloadPathTemplate) {
 | |
|   const { doc, update: update2 } = createNoticeDoc(`Download "${episode.title}"`);
 | |
|   const SOME_LARGE_INT_SO_THE_BOX_DOESNT_AUTO_CLOSE = 999999999;
 | |
|   const notice = new import_obsidian15.Notice(doc, SOME_LARGE_INT_SO_THE_BOX_DOESNT_AUTO_CLOSE);
 | |
|   update2((bodyEl) => bodyEl.createEl("p", { text: "Starting download..." }));
 | |
|   update2((bodyEl) => {
 | |
|     bodyEl.createEl("p", { text: "Downloading..." });
 | |
|   });
 | |
|   const { blob } = await downloadFile(episode.streamUrl, {
 | |
|     onFinished: () => {
 | |
|       update2((bodyEl) => bodyEl.createEl("p", { text: "Download complete!" }));
 | |
|     },
 | |
|     onError: (error) => {
 | |
|       update2((bodyEl) => bodyEl.createEl("p", {
 | |
|         text: `Download failed: ${error.message}`
 | |
|       }));
 | |
|     }
 | |
|   });
 | |
|   const fileExtension = await detectAudioFileExtension(blob);
 | |
|   if (!fileExtension) {
 | |
|     update2((bodyEl) => {
 | |
|       bodyEl.createEl("p", {
 | |
|         text: `Could not determine file extension for downloaded file. Blob: ${blob.size} bytes.`
 | |
|       });
 | |
|     });
 | |
|     throw new Error("Could not determine file extension");
 | |
|   }
 | |
|   if (!blob.type.contains("audio") && !fileExtension) {
 | |
|     update2((bodyEl) => {
 | |
|       bodyEl.createEl("p", {
 | |
|         text: `Downloaded file is not an audio file. It is of type "${blob.type}". Blob: ${blob.size} bytes.`
 | |
|       });
 | |
|     });
 | |
|     throw new Error("Not an audio file");
 | |
|   }
 | |
|   try {
 | |
|     update2((bodyEl) => bodyEl.createEl("p", { text: "Creating file..." }));
 | |
|     await createEpisodeFile({
 | |
|       episode,
 | |
|       downloadPathTemplate,
 | |
|       blob,
 | |
|       extension: fileExtension
 | |
|     });
 | |
|     update2((bodyEl) => bodyEl.createEl("p", {
 | |
|       text: `Successfully downloaded "${episode.title}" from ${episode.podcastName}.`
 | |
|     }));
 | |
|   } catch (error) {
 | |
|     update2((bodyEl) => {
 | |
|       bodyEl.createEl("p", {
 | |
|         text: `Failed to create file for downloaded episode "${episode.title}" from ${episode.podcastName}.`
 | |
|       });
 | |
|       const errorMsgEl = bodyEl.createEl("p", { text: error.message });
 | |
|       errorMsgEl.style.fontStyle = "italic";
 | |
|     });
 | |
|   }
 | |
|   setTimeout(() => notice.hide(), 1e4);
 | |
| }
 | |
| function createNoticeDoc(title) {
 | |
|   const doc = new DocumentFragment();
 | |
|   const container = doc.createDiv();
 | |
|   container.style.width = "100%";
 | |
|   container.style.display = "flex";
 | |
|   const titleEl = container.createEl("span", { text: title });
 | |
|   titleEl.style.textAlign = "center";
 | |
|   titleEl.style.fontWeight = "bold";
 | |
|   titleEl.style.marginBottom = "0.5em";
 | |
|   const bodyEl = doc.createDiv();
 | |
|   bodyEl.style.display = "flex";
 | |
|   bodyEl.style.flexDirection = "column";
 | |
|   bodyEl.style.alignItems = "center";
 | |
|   bodyEl.style.justifyContent = "center";
 | |
|   return {
 | |
|     doc,
 | |
|     update: (updateFn, empty2 = true) => {
 | |
|       if (empty2)
 | |
|         bodyEl.empty();
 | |
|       updateFn(bodyEl);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| async function createEpisodeFile({
 | |
|   episode,
 | |
|   downloadPathTemplate,
 | |
|   blob,
 | |
|   extension
 | |
| }) {
 | |
|   const basename = DownloadPathTemplateEngine(downloadPathTemplate, episode);
 | |
|   const filePath = `${basename}.${extension}`;
 | |
|   const buffer = await blob.arrayBuffer();
 | |
|   try {
 | |
|     await app.vault.createBinary(filePath, buffer);
 | |
|   } catch (error) {
 | |
|     throw new Error(`Failed to write file "${filePath}": ${error.message}`);
 | |
|   }
 | |
|   downloadedEpisodes.addEpisode(episode, filePath, blob.size);
 | |
| }
 | |
| async function downloadEpisode(episode, downloadPathTemplate) {
 | |
|   const basename = DownloadPathTemplateEngine(downloadPathTemplate, episode);
 | |
|   const fileExtension = await getFileExtension(episode.streamUrl);
 | |
|   const filePath = `${basename}.${fileExtension}`;
 | |
|   const existingFile = app.vault.getAbstractFileByPath(filePath);
 | |
|   if (existingFile instanceof import_obsidian15.TFile) {
 | |
|     return filePath;
 | |
|   }
 | |
|   try {
 | |
|     const { blob, responseUrl } = await downloadFile(episode.streamUrl);
 | |
|     if (!blob.type.includes("audio") && !fileExtension) {
 | |
|       throw new Error("Not an audio file.");
 | |
|     }
 | |
|     await createEpisodeFile({
 | |
|       episode,
 | |
|       downloadPathTemplate,
 | |
|       blob,
 | |
|       extension: fileExtension
 | |
|     });
 | |
|     return filePath;
 | |
|   } catch (error) {
 | |
|     throw new Error(`Failed to download ${episode.title}: ${error.message}`);
 | |
|   }
 | |
| }
 | |
| async function getFileExtension(url) {
 | |
|   const urlExtension = getUrlExtension(url);
 | |
|   if (urlExtension)
 | |
|     return urlExtension;
 | |
|   const response = await fetch(url, { method: "HEAD" });
 | |
|   const contentType = response.headers.get("content-type");
 | |
|   if (contentType?.includes("audio/mpeg"))
 | |
|     return "mp3";
 | |
|   if (contentType?.includes("audio/mp4"))
 | |
|     return "m4a";
 | |
|   if (contentType?.includes("audio/ogg"))
 | |
|     return "ogg";
 | |
|   if (contentType?.includes("audio/wav"))
 | |
|     return "wav";
 | |
|   if (contentType?.includes("audio/x-m4a"))
 | |
|     return "m4a";
 | |
|   return "mp3";
 | |
| }
 | |
| async function detectAudioFileExtension(blob) {
 | |
|   const audioSignatures = [
 | |
|     { signature: [255, 224], mask: [255, 224], fileExtension: "mp3" },
 | |
|     { signature: [73, 68, 51], fileExtension: "mp3" },
 | |
|     { signature: [82, 73, 70, 70], fileExtension: "wav" },
 | |
|     { signature: [79, 103, 103, 83], fileExtension: "ogg" },
 | |
|     { signature: [102, 76, 97, 67], fileExtension: "flac" },
 | |
|     { signature: [77, 52, 65, 32], fileExtension: "m4a" },
 | |
|     {
 | |
|       signature: [48, 38, 178, 117, 142, 102, 207, 17],
 | |
|       fileExtension: "wma"
 | |
|     },
 | |
|     {
 | |
|       signature: [35, 33, 65, 77, 82, 10],
 | |
|       fileExtension: "amr"
 | |
|     }
 | |
|   ];
 | |
|   return new Promise((resolve, reject) => {
 | |
|     const fileReader = new FileReader();
 | |
|     fileReader.onloadend = (e) => {
 | |
|       if (!e.target?.result) {
 | |
|         reject(new Error("No result from file reader"));
 | |
|         return;
 | |
|       }
 | |
|       const arr = new Uint8Array(e.target.result);
 | |
|       for (const { signature, mask, fileExtension } of audioSignatures) {
 | |
|         let matches = true;
 | |
|         for (let i = 0; i < signature.length; i++) {
 | |
|           if (mask) {
 | |
|             if ((arr[i] & mask[i]) !== (signature[i] & mask[i])) {
 | |
|               matches = false;
 | |
|               break;
 | |
|             }
 | |
|           } else {
 | |
|             if (arr[i] !== signature[i]) {
 | |
|               matches = false;
 | |
|               break;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|         if (matches) {
 | |
|           resolve(fileExtension);
 | |
|           return;
 | |
|         }
 | |
|       }
 | |
|       resolve(null);
 | |
|     };
 | |
|     fileReader.onerror = () => {
 | |
|       reject(fileReader.error);
 | |
|     };
 | |
|     fileReader.readAsArrayBuffer(blob.slice(0, Math.max(...audioSignatures.map((sig) => sig.signature.length))));
 | |
|   });
 | |
| }
 | |
| 
 | |
| // src/ui/PodcastView/spawnEpisodeContextMenu.ts
 | |
| function spawnEpisodeContextMenu(episode, event, disabledMenuItems) {
 | |
|   const menu = new import_obsidian16.Menu();
 | |
|   if (!disabledMenuItems?.play) {
 | |
|     menu.addItem((item) => item.setIcon("play").setTitle("Play").onClick(() => {
 | |
|       currentEpisode.set(episode);
 | |
|       viewState.set(2 /* Player */);
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.markPlayed) {
 | |
|     const episodeIsPlayed = Object.values(get_store_value(playedEpisodes)).find((e) => e.title === episode.title && e.finished);
 | |
|     menu.addItem((item) => item.setIcon(episodeIsPlayed ? "cross" : "check").setTitle(`Mark as ${episodeIsPlayed ? "Unplayed" : "Played"}`).onClick(() => {
 | |
|       if (episodeIsPlayed) {
 | |
|         playedEpisodes.markAsUnplayed(episode);
 | |
|       } else {
 | |
|         playedEpisodes.markAsPlayed(episode);
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.download) {
 | |
|     const isDownloaded = downloadedEpisodes.isEpisodeDownloaded(episode);
 | |
|     menu.addItem((item) => item.setIcon(isDownloaded ? "cross" : "download").setTitle(isDownloaded ? "Remove file" : "Download").onClick(() => {
 | |
|       if (isDownloaded) {
 | |
|         downloadedEpisodes.removeEpisode(episode, true);
 | |
|       } else {
 | |
|         const downloadPath = get_store_value(plugin).settings.download.path;
 | |
|         if (!downloadPath) {
 | |
|           new import_obsidian16.Notice(`Please set a download path in the settings.`);
 | |
|           return;
 | |
|         }
 | |
|         downloadEpisodeWithNotice(episode, downloadPath);
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.createNote) {
 | |
|     const episodeNoteExists = Boolean(getPodcastNote(episode));
 | |
|     menu.addItem((item) => item.setIcon("pencil").setTitle(`${episodeNoteExists ? "Open" : "Create"} Note`).onClick(async () => {
 | |
|       if (episodeNoteExists) {
 | |
|         openPodcastNote(episode);
 | |
|       } else {
 | |
|         const { path, template } = get_store_value(plugin).settings.note;
 | |
|         const canCreateNote = Boolean(path && template);
 | |
|         if (!canCreateNote) {
 | |
|           new import_obsidian16.Notice(`Please set a note path and template in the settings.`);
 | |
|           return;
 | |
|         }
 | |
|         await createPodcastNote(episode);
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.favorite) {
 | |
|     const episodeIsFavorite = get_store_value(favorites).episodes.find((e) => e.title === episode.title);
 | |
|     menu.addItem((item) => item.setIcon("lucide-star").setTitle(`${episodeIsFavorite ? "Remove from" : "Add to"} Favorites`).onClick(() => {
 | |
|       if (episodeIsFavorite) {
 | |
|         favorites.update((playlist) => {
 | |
|           playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title);
 | |
|           return playlist;
 | |
|         });
 | |
|       } else {
 | |
|         favorites.update((playlist) => {
 | |
|           const newEpisodes = [...playlist.episodes, episode];
 | |
|           playlist.episodes = newEpisodes;
 | |
|           return playlist;
 | |
|         });
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.queue) {
 | |
|     const episodeIsInQueue = get_store_value(queue).episodes.find((e) => e.title === episode.title);
 | |
|     menu.addItem((item) => item.setIcon("list-ordered").setTitle(`${episodeIsInQueue ? "Remove from" : "Add to"} Queue`).onClick(() => {
 | |
|       if (episodeIsInQueue) {
 | |
|         queue.update((playlist) => {
 | |
|           playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title);
 | |
|           return playlist;
 | |
|         });
 | |
|       } else {
 | |
|         queue.update((playlist) => {
 | |
|           const newEpisodes = [...playlist.episodes, episode];
 | |
|           playlist.episodes = newEpisodes;
 | |
|           return playlist;
 | |
|         });
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
|   if (!disabledMenuItems?.playlists) {
 | |
|     menu.addSeparator();
 | |
|     const playlistsInStore = get_store_value(playlists);
 | |
|     for (const playlist of Object.values(playlistsInStore)) {
 | |
|       const episodeIsInPlaylist = playlist.episodes.find((e) => e.title === episode.title);
 | |
|       menu.addItem((item) => item.setIcon(playlist.icon).setTitle(`${episodeIsInPlaylist ? "Remove from" : "Add to"} ${playlist.name}`).onClick(() => {
 | |
|         if (episodeIsInPlaylist) {
 | |
|           playlists.update((playlists2) => {
 | |
|             playlists2[playlist.name].episodes = playlists2[playlist.name].episodes.filter((e) => e.title !== episode.title);
 | |
|             return playlists2;
 | |
|           });
 | |
|         } else {
 | |
|           playlists.update((playlists2) => {
 | |
|             const newEpisodes = [...playlists2[playlist.name].episodes, episode];
 | |
|             playlists2[playlist.name].episodes = newEpisodes;
 | |
|             return playlists2;
 | |
|           });
 | |
|         }
 | |
|       }));
 | |
|     }
 | |
|   }
 | |
|   menu.showAtMouseEvent(event);
 | |
| }
 | |
| 
 | |
| // src/utility/createMediaUrlObjectFromFilePath.ts
 | |
| var import_obsidian17 = require("obsidian");
 | |
| async function createMediaUrlObjectFromFilePath(filePath) {
 | |
|   const file = app.vault.getAbstractFileByPath(filePath);
 | |
|   if (!file || !(file instanceof import_obsidian17.TFile))
 | |
|     return "";
 | |
|   const binary = await app.vault.readBinary(file);
 | |
|   return URL.createObjectURL(new Blob([binary], { type: "audio/mpeg" }));
 | |
| }
 | |
| 
 | |
| // src/ui/PodcastView/EpisodePlayer.svelte
 | |
| function add_css14(target) {
 | |
|   append_styles(target, "svelte-1itadba", ".episode-player{display:flex;flex-direction:column;height:100%}.episode-image-container{width:100%;height:auto;padding:5% 0%}.hover-container{min-width:10rem;min-height:10rem;width:100%;height:100%;aspect-ratio:1/1;display:flex;align-items:center;justify-content:center;position:relative;margin-left:auto;margin-right:auto}.podcast-artwork{width:100%;height:100%;background-size:cover;background-position:center;background-repeat:no-repeat;position:absolute}.podcast-artwork-placeholder{width:100%;height:100%;background-size:cover;background-position:center;background-repeat:no-repeat;position:absolute;display:flex;align-items:center;justify-content:center}.podcast-artwork:hover{cursor:pointer !important}.podcast-artwork-overlay{position:absolute}.podcast-artwork-isloading-overlay{position:absolute;display:block}.podcast-artwork-overlay:hover{cursor:pointer !important}.opacity-50{opacity:0.5}.podcast-title{font-size:1.5rem;font-weight:bold;margin:0%;margin-bottom:0.5rem;text-align:center}.status-container{display:flex;align-items:center;justify-content:space-around}.controls-container{display:flex;align-items:center;justify-content:space-between;margin-top:1rem;margin-left:25%;margin-right:25%}.playbackrate-container{display:flex;align-items:center;justify-content:space-around;margin-bottom:2.5rem;flex-direction:column;margin-top:auto}");
 | |
| }
 | |
| function create_fallback_slot(ctx) {
 | |
|   let div;
 | |
|   let icon;
 | |
|   let div_class_value;
 | |
|   let current;
 | |
|   icon = new Icon_default({ props: { icon: "image", size: 150 } });
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(icon.$$.fragment);
 | |
|       attr(div, "class", div_class_value = "podcast-artwork-placeholder" + (ctx[2] || ctx[9] ? " opacity-50" : ""));
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(icon, div, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (!current || dirty[0] & 516 && div_class_value !== (div_class_value = "podcast-artwork-placeholder" + (ctx2[2] || ctx2[9] ? " opacity-50" : ""))) {
 | |
|         attr(div, "class", div_class_value);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(icon);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_else_block3(ctx) {
 | |
|   let div;
 | |
|   let icon;
 | |
|   let div_style_value;
 | |
|   let current;
 | |
|   icon = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[9] ? "play" : "pause"
 | |
|     }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(icon.$$.fragment);
 | |
|       attr(div, "class", "podcast-artwork-overlay");
 | |
|       attr(div, "style", div_style_value = `display: ${ctx[2] || ctx[9] ? "block" : "none"}`);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(icon, div, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const icon_changes = {};
 | |
|       if (dirty[0] & 512)
 | |
|         icon_changes.icon = ctx2[9] ? "play" : "pause";
 | |
|       icon.$set(icon_changes);
 | |
|       if (!current || dirty[0] & 516 && div_style_value !== (div_style_value = `display: ${ctx2[2] || ctx2[9] ? "block" : "none"}`)) {
 | |
|         attr(div, "style", div_style_value);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(icon);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block8(ctx) {
 | |
|   let div;
 | |
|   let loading;
 | |
|   let current;
 | |
|   loading = new Loading_default({});
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(loading.$$.fragment);
 | |
|       attr(div, "class", "podcast-artwork-isloading-overlay");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(loading, div, null);
 | |
|       current = true;
 | |
|     },
 | |
|     p: noop,
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(loading.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(loading.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(loading);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_catch_block(ctx) {
 | |
|   return { c: noop, m: noop, p: noop, d: noop };
 | |
| }
 | |
| function create_then_block(ctx) {
 | |
|   let audio;
 | |
|   let audio_src_value;
 | |
|   let audio_autoplay_value;
 | |
|   let audio_updating = false;
 | |
|   let audio_animationframe;
 | |
|   let audio_is_paused = true;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   function audio_timeupdate_handler() {
 | |
|     cancelAnimationFrame(audio_animationframe);
 | |
|     if (!audio.paused) {
 | |
|       audio_animationframe = raf(audio_timeupdate_handler);
 | |
|       audio_updating = true;
 | |
|     }
 | |
|     ctx[23].call(audio);
 | |
|   }
 | |
|   return {
 | |
|     c() {
 | |
|       audio = element("audio");
 | |
|       if (!src_url_equal(audio.src, audio_src_value = ctx[31]))
 | |
|         attr(audio, "src", audio_src_value);
 | |
|       audio.autoplay = audio_autoplay_value = true;
 | |
|       if (ctx[6] === void 0)
 | |
|         add_render_callback(() => ctx[22].call(audio));
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, audio, anchor);
 | |
|       if (!isNaN(ctx[1]._playbackRate)) {
 | |
|         audio.playbackRate = ctx[1]._playbackRate;
 | |
|       }
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(audio, "durationchange", ctx[22]),
 | |
|           listen(audio, "timeupdate", audio_timeupdate_handler),
 | |
|           listen(audio, "play", ctx[24]),
 | |
|           listen(audio, "pause", ctx[24]),
 | |
|           listen(audio, "ratechange", ctx[25]),
 | |
|           listen(audio, "ended", ctx[13]),
 | |
|           listen(audio, "loadedmetadata", ctx[15]),
 | |
|           listen(audio, "play", prevent_default(ctx[19]))
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (dirty[0] & 16 && !src_url_equal(audio.src, audio_src_value = ctx2[31])) {
 | |
|         attr(audio, "src", audio_src_value);
 | |
|       }
 | |
|       if (!audio_updating && dirty[0] & 1 && !isNaN(ctx2[0])) {
 | |
|         audio.currentTime = ctx2[0];
 | |
|       }
 | |
|       audio_updating = false;
 | |
|       if (dirty[0] & 512 && audio_is_paused !== (audio_is_paused = ctx2[9])) {
 | |
|         audio[audio_is_paused ? "pause" : "play"]();
 | |
|       }
 | |
|       if (dirty[0] & 2 && !isNaN(ctx2[1]._playbackRate)) {
 | |
|         audio.playbackRate = ctx2[1]._playbackRate;
 | |
|       }
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(audio);
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_pending_block(ctx) {
 | |
|   return { c: noop, m: noop, p: noop, d: noop };
 | |
| }
 | |
| function create_header_slot(ctx) {
 | |
|   let h3;
 | |
|   return {
 | |
|     c() {
 | |
|       h3 = element("h3");
 | |
|       h3.textContent = "Queue";
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, h3, anchor);
 | |
|     },
 | |
|     p: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(h3);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment20(ctx) {
 | |
|   let div5;
 | |
|   let div1;
 | |
|   let div0;
 | |
|   let image;
 | |
|   let t0;
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let t1;
 | |
|   let h2;
 | |
|   let t2_value = ctx[5].title + "";
 | |
|   let t2;
 | |
|   let t3;
 | |
|   let promise2;
 | |
|   let t4;
 | |
|   let div2;
 | |
|   let span0;
 | |
|   let t5_value = formatSeconds(ctx[7], "HH:mm:ss") + "";
 | |
|   let t5;
 | |
|   let t6;
 | |
|   let progressbar;
 | |
|   let t7;
 | |
|   let span1;
 | |
|   let t8_value = formatSeconds(ctx[6] - ctx[7], "HH:mm:ss") + "";
 | |
|   let t8;
 | |
|   let t9;
 | |
|   let div3;
 | |
|   let button0;
 | |
|   let t10;
 | |
|   let button1;
 | |
|   let t11;
 | |
|   let div4;
 | |
|   let span2;
 | |
|   let t12_value = ctx[1].playbackRate + "";
 | |
|   let t12;
 | |
|   let t13;
 | |
|   let t14;
 | |
|   let slider;
 | |
|   let t15;
 | |
|   let episodelist;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   image = new Image_default({
 | |
|     props: {
 | |
|       class: "podcast-artwork",
 | |
|       src: ctx[5].artworkUrl ?? "",
 | |
|       alt: ctx[5].title,
 | |
|       opacity: ctx[2] || ctx[9] ? 0.5 : 1,
 | |
|       $$slots: { fallback: [create_fallback_slot] },
 | |
|       $$scope: { ctx }
 | |
|     }
 | |
|   });
 | |
|   const if_block_creators = [create_if_block8, create_else_block3];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[3])
 | |
|       return 0;
 | |
|     return 1;
 | |
|   }
 | |
|   current_block_type_index = select_block_type(ctx, [-1, -1]);
 | |
|   if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   let info = {
 | |
|     ctx,
 | |
|     current: null,
 | |
|     token: null,
 | |
|     hasCatch: false,
 | |
|     pending: create_pending_block,
 | |
|     then: create_then_block,
 | |
|     catch: create_catch_block,
 | |
|     value: 31
 | |
|   };
 | |
|   handle_promise(promise2 = ctx[4], info);
 | |
|   progressbar = new Progressbar_default({
 | |
|     props: {
 | |
|       value: ctx[7],
 | |
|       max: ctx[6],
 | |
|       style: { "height": "2rem" }
 | |
|     }
 | |
|   });
 | |
|   progressbar.$on("click", ctx[12]);
 | |
|   button0 = new Button_default({
 | |
|     props: {
 | |
|       icon: "skip-back",
 | |
|       tooltip: "Skip backward",
 | |
|       style: { margin: "0", cursor: "pointer" }
 | |
|     }
 | |
|   });
 | |
|   button0.$on("click", function() {
 | |
|     if (is_function(ctx[8].api.skipBackward.bind(ctx[8].api)))
 | |
|       ctx[8].api.skipBackward.bind(ctx[8].api).apply(this, arguments);
 | |
|   });
 | |
|   button1 = new Button_default({
 | |
|     props: {
 | |
|       icon: "skip-forward",
 | |
|       tooltip: "Skip forward",
 | |
|       style: { margin: "0", cursor: "pointer" }
 | |
|     }
 | |
|   });
 | |
|   button1.$on("click", function() {
 | |
|     if (is_function(ctx[8].api.skipForward.bind(ctx[8].api)))
 | |
|       ctx[8].api.skipForward.bind(ctx[8].api).apply(this, arguments);
 | |
|   });
 | |
|   slider = new Slider_default({
 | |
|     props: {
 | |
|       value: ctx[1].playbackRate,
 | |
|       limits: [0.5, 3.5, 0.1]
 | |
|     }
 | |
|   });
 | |
|   slider.$on("change", ctx[14]);
 | |
|   episodelist = new EpisodeList_default({
 | |
|     props: {
 | |
|       episodes: ctx[10].episodes,
 | |
|       showListMenu: false,
 | |
|       showThumbnails: true,
 | |
|       $$slots: { header: [create_header_slot] },
 | |
|       $$scope: { ctx }
 | |
|     }
 | |
|   });
 | |
|   episodelist.$on("contextMenuEpisode", ctx[16]);
 | |
|   episodelist.$on("clickEpisode", ctx[18]);
 | |
|   return {
 | |
|     c() {
 | |
|       div5 = element("div");
 | |
|       div1 = element("div");
 | |
|       div0 = element("div");
 | |
|       create_component(image.$$.fragment);
 | |
|       t0 = space();
 | |
|       if_block.c();
 | |
|       t1 = space();
 | |
|       h2 = element("h2");
 | |
|       t2 = text(t2_value);
 | |
|       t3 = space();
 | |
|       info.block.c();
 | |
|       t4 = space();
 | |
|       div2 = element("div");
 | |
|       span0 = element("span");
 | |
|       t5 = text(t5_value);
 | |
|       t6 = space();
 | |
|       create_component(progressbar.$$.fragment);
 | |
|       t7 = space();
 | |
|       span1 = element("span");
 | |
|       t8 = text(t8_value);
 | |
|       t9 = space();
 | |
|       div3 = element("div");
 | |
|       create_component(button0.$$.fragment);
 | |
|       t10 = space();
 | |
|       create_component(button1.$$.fragment);
 | |
|       t11 = space();
 | |
|       div4 = element("div");
 | |
|       span2 = element("span");
 | |
|       t12 = text(t12_value);
 | |
|       t13 = text("x");
 | |
|       t14 = space();
 | |
|       create_component(slider.$$.fragment);
 | |
|       t15 = space();
 | |
|       create_component(episodelist.$$.fragment);
 | |
|       attr(div0, "class", "hover-container");
 | |
|       attr(div1, "class", "episode-image-container");
 | |
|       attr(h2, "class", "podcast-title");
 | |
|       attr(div2, "class", "status-container");
 | |
|       attr(div3, "class", "controls-container");
 | |
|       attr(div4, "class", "playbackrate-container");
 | |
|       attr(div5, "class", "episode-player");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div5, anchor);
 | |
|       append(div5, div1);
 | |
|       append(div1, div0);
 | |
|       mount_component(image, div0, null);
 | |
|       append(div0, t0);
 | |
|       if_blocks[current_block_type_index].m(div0, null);
 | |
|       append(div5, t1);
 | |
|       append(div5, h2);
 | |
|       append(h2, t2);
 | |
|       append(div5, t3);
 | |
|       info.block.m(div5, info.anchor = null);
 | |
|       info.mount = () => div5;
 | |
|       info.anchor = t4;
 | |
|       append(div5, t4);
 | |
|       append(div5, div2);
 | |
|       append(div2, span0);
 | |
|       append(span0, t5);
 | |
|       append(div2, t6);
 | |
|       mount_component(progressbar, div2, null);
 | |
|       append(div2, t7);
 | |
|       append(div2, span1);
 | |
|       append(span1, t8);
 | |
|       append(div5, t9);
 | |
|       append(div5, div3);
 | |
|       mount_component(button0, div3, null);
 | |
|       append(div3, t10);
 | |
|       mount_component(button1, div3, null);
 | |
|       append(div5, t11);
 | |
|       append(div5, div4);
 | |
|       append(div4, span2);
 | |
|       append(span2, t12);
 | |
|       append(span2, t13);
 | |
|       append(div4, t14);
 | |
|       mount_component(slider, div4, null);
 | |
|       append(div5, t15);
 | |
|       mount_component(episodelist, div5, null);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(div0, "click", ctx[11]),
 | |
|           listen(div0, "contextmenu", ctx[17]),
 | |
|           listen(div0, "mouseenter", ctx[20]),
 | |
|           listen(div0, "mouseleave", ctx[21])
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(new_ctx, dirty) {
 | |
|       ctx = new_ctx;
 | |
|       const image_changes = {};
 | |
|       if (dirty[0] & 32)
 | |
|         image_changes.src = ctx[5].artworkUrl ?? "";
 | |
|       if (dirty[0] & 32)
 | |
|         image_changes.alt = ctx[5].title;
 | |
|       if (dirty[0] & 516)
 | |
|         image_changes.opacity = ctx[2] || ctx[9] ? 0.5 : 1;
 | |
|       if (dirty[0] & 516 | dirty[1] & 2) {
 | |
|         image_changes.$$scope = { dirty, ctx };
 | |
|       }
 | |
|       image.$set(image_changes);
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if_blocks[current_block_type_index].p(ctx, dirty);
 | |
|       } else {
 | |
|         group_outros();
 | |
|         transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|           if_blocks[previous_block_index] = null;
 | |
|         });
 | |
|         check_outros();
 | |
|         if_block = if_blocks[current_block_type_index];
 | |
|         if (!if_block) {
 | |
|           if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|           if_block.c();
 | |
|         } else {
 | |
|           if_block.p(ctx, dirty);
 | |
|         }
 | |
|         transition_in(if_block, 1);
 | |
|         if_block.m(div0, null);
 | |
|       }
 | |
|       if ((!current || dirty[0] & 32) && t2_value !== (t2_value = ctx[5].title + ""))
 | |
|         set_data(t2, t2_value);
 | |
|       info.ctx = ctx;
 | |
|       if (dirty[0] & 16 && promise2 !== (promise2 = ctx[4]) && handle_promise(promise2, info)) {
 | |
|       } else {
 | |
|         update_await_block_branch(info, ctx, dirty);
 | |
|       }
 | |
|       if ((!current || dirty[0] & 128) && t5_value !== (t5_value = formatSeconds(ctx[7], "HH:mm:ss") + ""))
 | |
|         set_data(t5, t5_value);
 | |
|       const progressbar_changes = {};
 | |
|       if (dirty[0] & 128)
 | |
|         progressbar_changes.value = ctx[7];
 | |
|       if (dirty[0] & 64)
 | |
|         progressbar_changes.max = ctx[6];
 | |
|       progressbar.$set(progressbar_changes);
 | |
|       if ((!current || dirty[0] & 192) && t8_value !== (t8_value = formatSeconds(ctx[6] - ctx[7], "HH:mm:ss") + ""))
 | |
|         set_data(t8, t8_value);
 | |
|       if ((!current || dirty[0] & 2) && t12_value !== (t12_value = ctx[1].playbackRate + ""))
 | |
|         set_data(t12, t12_value);
 | |
|       const slider_changes = {};
 | |
|       if (dirty[0] & 2)
 | |
|         slider_changes.value = ctx[1].playbackRate;
 | |
|       slider.$set(slider_changes);
 | |
|       const episodelist_changes = {};
 | |
|       if (dirty[0] & 1024)
 | |
|         episodelist_changes.episodes = ctx[10].episodes;
 | |
|       if (dirty[1] & 2) {
 | |
|         episodelist_changes.$$scope = { dirty, ctx };
 | |
|       }
 | |
|       episodelist.$set(episodelist_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(image.$$.fragment, local);
 | |
|       transition_in(if_block);
 | |
|       transition_in(progressbar.$$.fragment, local);
 | |
|       transition_in(button0.$$.fragment, local);
 | |
|       transition_in(button1.$$.fragment, local);
 | |
|       transition_in(slider.$$.fragment, local);
 | |
|       transition_in(episodelist.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(image.$$.fragment, local);
 | |
|       transition_out(if_block);
 | |
|       transition_out(progressbar.$$.fragment, local);
 | |
|       transition_out(button0.$$.fragment, local);
 | |
|       transition_out(button1.$$.fragment, local);
 | |
|       transition_out(slider.$$.fragment, local);
 | |
|       transition_out(episodelist.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div5);
 | |
|       destroy_component(image);
 | |
|       if_blocks[current_block_type_index].d();
 | |
|       info.block.d();
 | |
|       info.token = null;
 | |
|       info = null;
 | |
|       destroy_component(progressbar);
 | |
|       destroy_component(button0);
 | |
|       destroy_component(button1);
 | |
|       destroy_component(slider);
 | |
|       destroy_component(episodelist);
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance19($$self, $$props, $$invalidate) {
 | |
|   let $currentEpisode;
 | |
|   let $duration;
 | |
|   let $currentTime;
 | |
|   let $playedEpisodes;
 | |
|   let $plugin;
 | |
|   let $isPaused;
 | |
|   let $queue;
 | |
|   component_subscribe($$self, currentEpisode, ($$value) => $$invalidate(5, $currentEpisode = $$value));
 | |
|   component_subscribe($$self, duration, ($$value) => $$invalidate(6, $duration = $$value));
 | |
|   component_subscribe($$self, currentTime, ($$value) => $$invalidate(7, $currentTime = $$value));
 | |
|   component_subscribe($$self, playedEpisodes, ($$value) => $$invalidate(26, $playedEpisodes = $$value));
 | |
|   component_subscribe($$self, plugin, ($$value) => $$invalidate(8, $plugin = $$value));
 | |
|   component_subscribe($$self, isPaused, ($$value) => $$invalidate(9, $isPaused = $$value));
 | |
|   component_subscribe($$self, queue, ($$value) => $$invalidate(10, $queue = $$value));
 | |
|   class CircumentForcedTwoWayBinding {
 | |
|     constructor() {
 | |
|       this.playbackRate = $plugin.settings.defaultPlaybackRate || 1;
 | |
|     }
 | |
|     get _playbackRate() {
 | |
|       return this.playbackRate;
 | |
|     }
 | |
|   }
 | |
|   const offBinding = new CircumentForcedTwoWayBinding();
 | |
|   let isHoveringArtwork = false;
 | |
|   let isLoading = true;
 | |
|   function togglePlayback() {
 | |
|     isPaused.update((value) => !value);
 | |
|   }
 | |
|   function onClickProgressbar({ detail: { event } }) {
 | |
|     const progressbar = event.target;
 | |
|     const percent = event.offsetX / progressbar.offsetWidth;
 | |
|     currentTime.set(percent * $duration);
 | |
|   }
 | |
|   function removeEpisodeFromPlaylists() {
 | |
|     playlists.update((lists) => {
 | |
|       Object.values(lists).forEach((playlist) => {
 | |
|         playlist.episodes = playlist.episodes.filter((ep) => ep.title !== $currentEpisode.title);
 | |
|       });
 | |
|       return lists;
 | |
|     });
 | |
|     queue.remove($currentEpisode);
 | |
|   }
 | |
|   function onEpisodeEnded() {
 | |
|     playedEpisodes.markAsPlayed($currentEpisode);
 | |
|     removeEpisodeFromPlaylists();
 | |
|     queue.playNext();
 | |
|   }
 | |
|   function onPlaybackRateChange(event) {
 | |
|     $$invalidate(1, offBinding.playbackRate = event.detail.value, offBinding);
 | |
|   }
 | |
|   function onMetadataLoaded() {
 | |
|     $$invalidate(3, isLoading = false);
 | |
|     restorePlaybackTime();
 | |
|   }
 | |
|   function restorePlaybackTime() {
 | |
|     const playedEps = $playedEpisodes;
 | |
|     const currentEp = $currentEpisode;
 | |
|     if (playedEps[currentEp.title]) {
 | |
|       currentTime.set(playedEps[currentEp.title].time);
 | |
|     } else {
 | |
|       currentTime.set(0);
 | |
|     }
 | |
|     isPaused.set(false);
 | |
|   }
 | |
|   let srcPromise = getSrc($currentEpisode);
 | |
|   let playerTime = 0;
 | |
|   onMount(() => {
 | |
|     const unsub = currentTime.subscribe((ct) => {
 | |
|       $$invalidate(0, playerTime = ct);
 | |
|     });
 | |
|     const unsubDownloadedSource = downloadedEpisodes.subscribe((_) => {
 | |
|       $$invalidate(4, srcPromise = getSrc($currentEpisode));
 | |
|     });
 | |
|     const unsubCurrentEpisode = currentEpisode.subscribe((_) => {
 | |
|       $$invalidate(4, srcPromise = getSrc($currentEpisode));
 | |
|     });
 | |
|     return () => {
 | |
|       unsub();
 | |
|       unsubDownloadedSource();
 | |
|       unsubCurrentEpisode();
 | |
|     };
 | |
|   });
 | |
|   onDestroy(() => {
 | |
|     playedEpisodes.setEpisodeTime($currentEpisode, $currentTime, $duration, $currentTime === $duration);
 | |
|     isPaused.set(true);
 | |
|   });
 | |
|   function handleContextMenuEpisode({ detail: { event, episode } }) {
 | |
|     spawnEpisodeContextMenu(episode, event);
 | |
|   }
 | |
|   function handleContextMenuEpisodeImage(event) {
 | |
|     spawnEpisodeContextMenu($currentEpisode, event, { play: true, markPlayed: true });
 | |
|   }
 | |
|   function handleClickEpisode(event) {
 | |
|     const { episode } = event.detail;
 | |
|     currentEpisode.set(episode);
 | |
|     viewState.set(2 /* Player */);
 | |
|   }
 | |
|   function getSrc(episode) {
 | |
|     return __awaiter(this, void 0, void 0, function* () {
 | |
|       if (downloadedEpisodes.isEpisodeDownloaded(episode)) {
 | |
|         const downloadedEpisode = downloadedEpisodes.getEpisode(episode);
 | |
|         if (!downloadedEpisode)
 | |
|           return "";
 | |
|         return createMediaUrlObjectFromFilePath(downloadedEpisode.filePath);
 | |
|       }
 | |
|       return episode.streamUrl;
 | |
|     });
 | |
|   }
 | |
|   function play_handler(event) {
 | |
|     bubble.call(this, $$self, event);
 | |
|   }
 | |
|   const mouseenter_handler = () => $$invalidate(2, isHoveringArtwork = true);
 | |
|   const mouseleave_handler = () => $$invalidate(2, isHoveringArtwork = false);
 | |
|   function audio_durationchange_handler() {
 | |
|     $duration = this.duration;
 | |
|     duration.set($duration);
 | |
|   }
 | |
|   function audio_timeupdate_handler() {
 | |
|     playerTime = this.currentTime;
 | |
|     $$invalidate(0, playerTime);
 | |
|   }
 | |
|   function audio_play_pause_handler() {
 | |
|     $isPaused = this.paused;
 | |
|     isPaused.set($isPaused);
 | |
|   }
 | |
|   function audio_ratechange_handler() {
 | |
|     offBinding._playbackRate = this.playbackRate;
 | |
|     $$invalidate(1, offBinding);
 | |
|   }
 | |
|   $$self.$$.update = () => {
 | |
|     if ($$self.$$.dirty[0] & 1) {
 | |
|       $: {
 | |
|         currentTime.set(playerTime);
 | |
|       }
 | |
|     }
 | |
|   };
 | |
|   return [
 | |
|     playerTime,
 | |
|     offBinding,
 | |
|     isHoveringArtwork,
 | |
|     isLoading,
 | |
|     srcPromise,
 | |
|     $currentEpisode,
 | |
|     $duration,
 | |
|     $currentTime,
 | |
|     $plugin,
 | |
|     $isPaused,
 | |
|     $queue,
 | |
|     togglePlayback,
 | |
|     onClickProgressbar,
 | |
|     onEpisodeEnded,
 | |
|     onPlaybackRateChange,
 | |
|     onMetadataLoaded,
 | |
|     handleContextMenuEpisode,
 | |
|     handleContextMenuEpisodeImage,
 | |
|     handleClickEpisode,
 | |
|     play_handler,
 | |
|     mouseenter_handler,
 | |
|     mouseleave_handler,
 | |
|     audio_durationchange_handler,
 | |
|     audio_timeupdate_handler,
 | |
|     audio_play_pause_handler,
 | |
|     audio_ratechange_handler
 | |
|   ];
 | |
| }
 | |
| var EpisodePlayer = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance19, create_fragment20, safe_not_equal, {}, add_css14, [-1, -1]);
 | |
|   }
 | |
| };
 | |
| var EpisodePlayer_default = EpisodePlayer;
 | |
| 
 | |
| // src/ui/PodcastView/TopBar.svelte
 | |
| function add_css15(target) {
 | |
|   append_styles(target, "svelte-shb2ik", ".topbar-container.svelte-shb2ik{display:flex;flex-direction:row;align-items:center;justify-content:space-between;height:50px;min-height:50px;border-bottom:1px solid var(--background-divider)}.topbar-menu-button.svelte-shb2ik{display:flex;align-items:center;justify-content:center;width:100%;height:100%;opacity:0.1}.topbar-selected.svelte-shb2ik{opacity:1 !important}.topbar-selectable.svelte-shb2ik{cursor:pointer;opacity:0.5}");
 | |
| }
 | |
| function create_fragment21(ctx) {
 | |
|   let div3;
 | |
|   let div0;
 | |
|   let icon0;
 | |
|   let div0_class_value;
 | |
|   let t0;
 | |
|   let div1;
 | |
|   let icon1;
 | |
|   let div1_class_value;
 | |
|   let t1;
 | |
|   let div2;
 | |
|   let icon2;
 | |
|   let div2_class_value;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   icon0 = new Icon_default({ props: { icon: "grid", size: 20 } });
 | |
|   icon1 = new Icon_default({ props: { icon: "list-minus", size: 20 } });
 | |
|   icon2 = new Icon_default({ props: { icon: "play", size: 20 } });
 | |
|   return {
 | |
|     c() {
 | |
|       div3 = element("div");
 | |
|       div0 = element("div");
 | |
|       create_component(icon0.$$.fragment);
 | |
|       t0 = space();
 | |
|       div1 = element("div");
 | |
|       create_component(icon1.$$.fragment);
 | |
|       t1 = space();
 | |
|       div2 = element("div");
 | |
|       create_component(icon2.$$.fragment);
 | |
|       attr(div0, "class", div0_class_value = null_to_empty(`
 | |
|             topbar-menu-button
 | |
|             topbar-selectable
 | |
|             ${ctx[0] === 0 /* PodcastGrid */ ? "topbar-selected" : ""}
 | |
|         `) + " svelte-shb2ik");
 | |
|       attr(div0, "aria-label", "Podcast grid");
 | |
|       attr(div1, "class", div1_class_value = null_to_empty(`
 | |
|             topbar-menu-button 
 | |
|             ${ctx[0] === 1 /* EpisodeList */ ? "topbar-selected" : ""}
 | |
|             ${ctx[1] ? "topbar-selectable" : ""}
 | |
|         `) + " svelte-shb2ik");
 | |
|       attr(div1, "aria-label", "Episode list");
 | |
|       attr(div2, "class", div2_class_value = null_to_empty(`
 | |
|             topbar-menu-button 
 | |
|             ${ctx[0] === 2 /* Player */ ? "topbar-selected" : ""}
 | |
|             ${ctx[2] ? "topbar-selectable" : ""}
 | |
|         `) + " svelte-shb2ik");
 | |
|       attr(div2, "aria-label", "Player");
 | |
|       attr(div3, "class", "topbar-container svelte-shb2ik");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div3, anchor);
 | |
|       append(div3, div0);
 | |
|       mount_component(icon0, div0, null);
 | |
|       append(div3, t0);
 | |
|       append(div3, div1);
 | |
|       mount_component(icon1, div1, null);
 | |
|       append(div3, t1);
 | |
|       append(div3, div2);
 | |
|       mount_component(icon2, div2, null);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = [
 | |
|           listen(div0, "click", ctx[3].bind(null, 0 /* PodcastGrid */)),
 | |
|           listen(div1, "click", ctx[3].bind(null, 1 /* EpisodeList */)),
 | |
|           listen(div2, "click", ctx[3].bind(null, 2 /* Player */))
 | |
|         ];
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (!current || dirty & 1 && div0_class_value !== (div0_class_value = null_to_empty(`
 | |
|             topbar-menu-button
 | |
|             topbar-selectable
 | |
|             ${ctx2[0] === 0 /* PodcastGrid */ ? "topbar-selected" : ""}
 | |
|         `) + " svelte-shb2ik")) {
 | |
|         attr(div0, "class", div0_class_value);
 | |
|       }
 | |
|       if (!current || dirty & 3 && div1_class_value !== (div1_class_value = null_to_empty(`
 | |
|             topbar-menu-button 
 | |
|             ${ctx2[0] === 1 /* EpisodeList */ ? "topbar-selected" : ""}
 | |
|             ${ctx2[1] ? "topbar-selectable" : ""}
 | |
|         `) + " svelte-shb2ik")) {
 | |
|         attr(div1, "class", div1_class_value);
 | |
|       }
 | |
|       if (!current || dirty & 5 && div2_class_value !== (div2_class_value = null_to_empty(`
 | |
|             topbar-menu-button 
 | |
|             ${ctx2[0] === 2 /* Player */ ? "topbar-selected" : ""}
 | |
|             ${ctx2[2] ? "topbar-selectable" : ""}
 | |
|         `) + " svelte-shb2ik")) {
 | |
|         attr(div2, "class", div2_class_value);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon0.$$.fragment, local);
 | |
|       transition_in(icon1.$$.fragment, local);
 | |
|       transition_in(icon2.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon0.$$.fragment, local);
 | |
|       transition_out(icon1.$$.fragment, local);
 | |
|       transition_out(icon2.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div3);
 | |
|       destroy_component(icon0);
 | |
|       destroy_component(icon1);
 | |
|       destroy_component(icon2);
 | |
|       mounted = false;
 | |
|       run_all(dispose);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance20($$self, $$props, $$invalidate) {
 | |
|   let { viewState: viewState2 = 0 /* PodcastGrid */ } = $$props;
 | |
|   let { canShowEpisodeList = false } = $$props;
 | |
|   let { canShowPlayer = false } = $$props;
 | |
|   function handleClickMenuItem(newState) {
 | |
|     if (viewState2 === newState)
 | |
|       return;
 | |
|     if (newState === 1 /* EpisodeList */ && !canShowEpisodeList)
 | |
|       return;
 | |
|     if (newState === 2 /* Player */ && !canShowPlayer)
 | |
|       return;
 | |
|     $$invalidate(0, viewState2 = newState);
 | |
|   }
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("viewState" in $$props2)
 | |
|       $$invalidate(0, viewState2 = $$props2.viewState);
 | |
|     if ("canShowEpisodeList" in $$props2)
 | |
|       $$invalidate(1, canShowEpisodeList = $$props2.canShowEpisodeList);
 | |
|     if ("canShowPlayer" in $$props2)
 | |
|       $$invalidate(2, canShowPlayer = $$props2.canShowPlayer);
 | |
|   };
 | |
|   return [viewState2, canShowEpisodeList, canShowPlayer, handleClickMenuItem];
 | |
| }
 | |
| var TopBar = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance20, create_fragment21, safe_not_equal, {
 | |
|       viewState: 0,
 | |
|       canShowEpisodeList: 1,
 | |
|       canShowPlayer: 2
 | |
|     }, add_css15);
 | |
|   }
 | |
| };
 | |
| var TopBar_default = TopBar;
 | |
| 
 | |
| // src/ui/PodcastView/EpisodeListHeader.svelte
 | |
| function add_css16(target) {
 | |
|   append_styles(target, "svelte-uuatlf", ".podcast-header.svelte-uuatlf{display:flex;flex-direction:column;justify-content:space-around;align-items:center;padding:0.5rem}.podcast-heading.svelte-uuatlf{text-align:center}");
 | |
| }
 | |
| function create_if_block9(ctx) {
 | |
|   let img;
 | |
|   let img_src_value;
 | |
|   return {
 | |
|     c() {
 | |
|       img = element("img");
 | |
|       attr(img, "id", "podcast-artwork");
 | |
|       if (!src_url_equal(img.src, img_src_value = ctx[1]))
 | |
|         attr(img, "src", img_src_value);
 | |
|       attr(img, "alt", ctx[0]);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, img, anchor);
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       if (dirty & 2 && !src_url_equal(img.src, img_src_value = ctx2[1])) {
 | |
|         attr(img, "src", img_src_value);
 | |
|       }
 | |
|       if (dirty & 1) {
 | |
|         attr(img, "alt", ctx2[0]);
 | |
|       }
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(img);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment22(ctx) {
 | |
|   let div;
 | |
|   let t0;
 | |
|   let h2;
 | |
|   let t1;
 | |
|   let if_block = ctx[1] && create_if_block9(ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       t0 = space();
 | |
|       h2 = element("h2");
 | |
|       t1 = text(ctx[0]);
 | |
|       attr(h2, "class", "podcast-heading svelte-uuatlf");
 | |
|       attr(div, "class", "podcast-header svelte-uuatlf");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       if (if_block)
 | |
|         if_block.m(div, null);
 | |
|       append(div, t0);
 | |
|       append(div, h2);
 | |
|       append(h2, t1);
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       if (ctx2[1]) {
 | |
|         if (if_block) {
 | |
|           if_block.p(ctx2, dirty);
 | |
|         } else {
 | |
|           if_block = create_if_block9(ctx2);
 | |
|           if_block.c();
 | |
|           if_block.m(div, t0);
 | |
|         }
 | |
|       } else if (if_block) {
 | |
|         if_block.d(1);
 | |
|         if_block = null;
 | |
|       }
 | |
|       if (dirty & 1)
 | |
|         set_data(t1, ctx2[0]);
 | |
|     },
 | |
|     i: noop,
 | |
|     o: noop,
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       if (if_block)
 | |
|         if_block.d();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance21($$self, $$props, $$invalidate) {
 | |
|   let { text: text2 = "" } = $$props;
 | |
|   let { artworkUrl = "" } = $$props;
 | |
|   $$self.$$set = ($$props2) => {
 | |
|     if ("text" in $$props2)
 | |
|       $$invalidate(0, text2 = $$props2.text);
 | |
|     if ("artworkUrl" in $$props2)
 | |
|       $$invalidate(1, artworkUrl = $$props2.artworkUrl);
 | |
|   };
 | |
|   return [text2, artworkUrl];
 | |
| }
 | |
| var EpisodeListHeader = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance21, create_fragment22, safe_not_equal, { text: 0, artworkUrl: 1 }, add_css16);
 | |
|   }
 | |
| };
 | |
| var EpisodeListHeader_default = EpisodeListHeader;
 | |
| 
 | |
| // src/ui/PodcastView/PodcastView.svelte
 | |
| var import_obsidian18 = require("obsidian");
 | |
| 
 | |
| // src/utility/searchEpisodes.ts
 | |
| function searchEpisodes(query, episodes) {
 | |
|   if (episodes.length === 0)
 | |
|     return [];
 | |
|   if (query.length === 0) {
 | |
|     return episodes;
 | |
|   }
 | |
|   const fuse = new Fuse(episodes, {
 | |
|     shouldSort: true,
 | |
|     findAllMatches: true,
 | |
|     threshold: 0.4,
 | |
|     isCaseSensitive: false,
 | |
|     keys: ["title"]
 | |
|   });
 | |
|   const searchResults = fuse.search(query);
 | |
|   return searchResults.map((resItem) => resItem.item);
 | |
| }
 | |
| 
 | |
| // src/ui/PodcastView/PodcastView.svelte
 | |
| function add_css17(target) {
 | |
|   append_styles(target, "svelte-unmvd4", ".podcast-view.svelte-unmvd4{display:flex;flex-direction:column;height:100%}.go-back.svelte-unmvd4{display:flex;align-items:center;justify-content:center;padding:0.5rem;gap:0.5rem;cursor:pointer;margin-right:auto;opacity:0.75}.go-back.svelte-unmvd4:hover{opacity:1}");
 | |
| }
 | |
| function create_if_block_4(ctx) {
 | |
|   let podcastgrid;
 | |
|   let current;
 | |
|   podcastgrid = new PodcastGrid_default({
 | |
|     props: {
 | |
|       feeds: ctx[0],
 | |
|       playlists: ctx[4]
 | |
|     }
 | |
|   });
 | |
|   podcastgrid.$on("clickPodcast", ctx[9]);
 | |
|   podcastgrid.$on("clickPlaylist", ctx[14]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(podcastgrid.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(podcastgrid, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const podcastgrid_changes = {};
 | |
|       if (dirty & 1)
 | |
|         podcastgrid_changes.feeds = ctx2[0];
 | |
|       if (dirty & 16)
 | |
|         podcastgrid_changes.playlists = ctx2[4];
 | |
|       podcastgrid.$set(podcastgrid_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(podcastgrid.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(podcastgrid.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(podcastgrid, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block_15(ctx) {
 | |
|   let episodelist;
 | |
|   let current;
 | |
|   episodelist = new EpisodeList_default({
 | |
|     props: {
 | |
|       episodes: ctx[3],
 | |
|       showThumbnails: !ctx[1] || !ctx[2],
 | |
|       $$slots: { header: [create_header_slot2] },
 | |
|       $$scope: { ctx }
 | |
|     }
 | |
|   });
 | |
|   episodelist.$on("clickEpisode", ctx[10]);
 | |
|   episodelist.$on("contextMenuEpisode", ctx[11]);
 | |
|   episodelist.$on("clickRefresh", ctx[12]);
 | |
|   episodelist.$on("search", ctx[13]);
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(episodelist.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(episodelist, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const episodelist_changes = {};
 | |
|       if (dirty & 8)
 | |
|         episodelist_changes.episodes = ctx2[3];
 | |
|       if (dirty & 6)
 | |
|         episodelist_changes.showThumbnails = !ctx2[1] || !ctx2[2];
 | |
|       if (dirty & 67108910) {
 | |
|         episodelist_changes.$$scope = { dirty, ctx: ctx2 };
 | |
|       }
 | |
|       episodelist.$set(episodelist_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(episodelist.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(episodelist.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(episodelist, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block10(ctx) {
 | |
|   let episodeplayer;
 | |
|   let current;
 | |
|   episodeplayer = new EpisodePlayer_default({});
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(episodeplayer.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(episodeplayer, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p: noop,
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(episodeplayer.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(episodeplayer.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(episodeplayer, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_else_block4(ctx) {
 | |
|   let episodelistheader;
 | |
|   let current;
 | |
|   episodelistheader = new EpisodeListHeader_default({ props: { text: "Latest Episodes" } });
 | |
|   return {
 | |
|     c() {
 | |
|       create_component(episodelistheader.$$.fragment);
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       mount_component(episodelistheader, target, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p: noop,
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(episodelistheader.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(episodelistheader.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       destroy_component(episodelistheader, detaching);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block_3(ctx) {
 | |
|   let span;
 | |
|   let icon0;
 | |
|   let t0;
 | |
|   let t1;
 | |
|   let div;
 | |
|   let icon1;
 | |
|   let t2;
 | |
|   let episodelistheader;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   icon0 = new Icon_default({
 | |
|     props: {
 | |
|       icon: "arrow-left",
 | |
|       style: { display: "flex", "align-items": "center" },
 | |
|       size: 20
 | |
|     }
 | |
|   });
 | |
|   icon1 = new Icon_default({
 | |
|     props: {
 | |
|       icon: ctx[2].icon,
 | |
|       size: 40,
 | |
|       clickable: false
 | |
|     }
 | |
|   });
 | |
|   episodelistheader = new EpisodeListHeader_default({
 | |
|     props: { text: ctx[2].name }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|       create_component(icon0.$$.fragment);
 | |
|       t0 = text(" Latest Episodes");
 | |
|       t1 = space();
 | |
|       div = element("div");
 | |
|       create_component(icon1.$$.fragment);
 | |
|       t2 = space();
 | |
|       create_component(episodelistheader.$$.fragment);
 | |
|       attr(span, "class", "go-back svelte-unmvd4");
 | |
|       set_style(div, "display", "flex");
 | |
|       set_style(div, "align-items", "center");
 | |
|       set_style(div, "justify-content", "center");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       mount_component(icon0, span, null);
 | |
|       append(span, t0);
 | |
|       insert(target, t1, anchor);
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(icon1, div, null);
 | |
|       insert(target, t2, anchor);
 | |
|       mount_component(episodelistheader, target, anchor);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = listen(span, "click", ctx[17]);
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const icon1_changes = {};
 | |
|       if (dirty & 4)
 | |
|         icon1_changes.icon = ctx2[2].icon;
 | |
|       icon1.$set(icon1_changes);
 | |
|       const episodelistheader_changes = {};
 | |
|       if (dirty & 4)
 | |
|         episodelistheader_changes.text = ctx2[2].name;
 | |
|       episodelistheader.$set(episodelistheader_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon0.$$.fragment, local);
 | |
|       transition_in(icon1.$$.fragment, local);
 | |
|       transition_in(episodelistheader.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon0.$$.fragment, local);
 | |
|       transition_out(icon1.$$.fragment, local);
 | |
|       transition_out(episodelistheader.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       destroy_component(icon0);
 | |
|       if (detaching)
 | |
|         detach(t1);
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(icon1);
 | |
|       if (detaching)
 | |
|         detach(t2);
 | |
|       destroy_component(episodelistheader, detaching);
 | |
|       mounted = false;
 | |
|       dispose();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_if_block_22(ctx) {
 | |
|   let span;
 | |
|   let icon;
 | |
|   let t0;
 | |
|   let t1;
 | |
|   let episodelistheader;
 | |
|   let current;
 | |
|   let mounted;
 | |
|   let dispose;
 | |
|   icon = new Icon_default({
 | |
|     props: {
 | |
|       icon: "arrow-left",
 | |
|       style: { display: "flex", "align-items": "center" },
 | |
|       size: 20
 | |
|     }
 | |
|   });
 | |
|   episodelistheader = new EpisodeListHeader_default({
 | |
|     props: {
 | |
|       text: ctx[1].title,
 | |
|       artworkUrl: ctx[1].artworkUrl
 | |
|     }
 | |
|   });
 | |
|   return {
 | |
|     c() {
 | |
|       span = element("span");
 | |
|       create_component(icon.$$.fragment);
 | |
|       t0 = text(" Latest Episodes");
 | |
|       t1 = space();
 | |
|       create_component(episodelistheader.$$.fragment);
 | |
|       attr(span, "class", "go-back svelte-unmvd4");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, span, anchor);
 | |
|       mount_component(icon, span, null);
 | |
|       append(span, t0);
 | |
|       insert(target, t1, anchor);
 | |
|       mount_component(episodelistheader, target, anchor);
 | |
|       current = true;
 | |
|       if (!mounted) {
 | |
|         dispose = listen(span, "click", ctx[16]);
 | |
|         mounted = true;
 | |
|       }
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       const episodelistheader_changes = {};
 | |
|       if (dirty & 2)
 | |
|         episodelistheader_changes.text = ctx2[1].title;
 | |
|       if (dirty & 2)
 | |
|         episodelistheader_changes.artworkUrl = ctx2[1].artworkUrl;
 | |
|       episodelistheader.$set(episodelistheader_changes);
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(icon.$$.fragment, local);
 | |
|       transition_in(episodelistheader.$$.fragment, local);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(icon.$$.fragment, local);
 | |
|       transition_out(episodelistheader.$$.fragment, local);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(span);
 | |
|       destroy_component(icon);
 | |
|       if (detaching)
 | |
|         detach(t1);
 | |
|       destroy_component(episodelistheader, detaching);
 | |
|       mounted = false;
 | |
|       dispose();
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_header_slot2(ctx) {
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let if_block_anchor;
 | |
|   let current;
 | |
|   const if_block_creators = [create_if_block_22, create_if_block_3, create_else_block4];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type_1(ctx2, dirty) {
 | |
|     if (ctx2[1])
 | |
|       return 0;
 | |
|     if (ctx2[2])
 | |
|       return 1;
 | |
|     return 2;
 | |
|   }
 | |
|   current_block_type_index = select_block_type_1(ctx, -1);
 | |
|   if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   return {
 | |
|     c() {
 | |
|       if_block.c();
 | |
|       if_block_anchor = empty();
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       if_blocks[current_block_type_index].m(target, anchor);
 | |
|       insert(target, if_block_anchor, anchor);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, dirty) {
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type_1(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|       } else {
 | |
|         group_outros();
 | |
|         transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|           if_blocks[previous_block_index] = null;
 | |
|         });
 | |
|         check_outros();
 | |
|         if_block = if_blocks[current_block_type_index];
 | |
|         if (!if_block) {
 | |
|           if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|           if_block.c();
 | |
|         } else {
 | |
|           if_block.p(ctx2, dirty);
 | |
|         }
 | |
|         transition_in(if_block, 1);
 | |
|         if_block.m(if_block_anchor.parentNode, if_block_anchor);
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if_blocks[current_block_type_index].d(detaching);
 | |
|       if (detaching)
 | |
|         detach(if_block_anchor);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function create_fragment23(ctx) {
 | |
|   let div;
 | |
|   let topbar;
 | |
|   let updating_viewState;
 | |
|   let t;
 | |
|   let current_block_type_index;
 | |
|   let if_block;
 | |
|   let current;
 | |
|   function topbar_viewState_binding(value) {
 | |
|     ctx[15](value);
 | |
|   }
 | |
|   let topbar_props = {
 | |
|     canShowEpisodeList: true,
 | |
|     canShowPlayer: !!ctx[6]
 | |
|   };
 | |
|   if (ctx[8] !== void 0) {
 | |
|     topbar_props.viewState = ctx[8];
 | |
|   }
 | |
|   topbar = new TopBar_default({ props: topbar_props });
 | |
|   binding_callbacks.push(() => bind(topbar, "viewState", topbar_viewState_binding));
 | |
|   const if_block_creators = [create_if_block10, create_if_block_15, create_if_block_4];
 | |
|   const if_blocks = [];
 | |
|   function select_block_type(ctx2, dirty) {
 | |
|     if (ctx2[8] === 2 /* Player */)
 | |
|       return 0;
 | |
|     if (ctx2[8] === 1 /* EpisodeList */)
 | |
|       return 1;
 | |
|     if (ctx2[8] === 0 /* PodcastGrid */)
 | |
|       return 2;
 | |
|     return -1;
 | |
|   }
 | |
|   if (~(current_block_type_index = select_block_type(ctx, -1))) {
 | |
|     if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
 | |
|   }
 | |
|   return {
 | |
|     c() {
 | |
|       div = element("div");
 | |
|       create_component(topbar.$$.fragment);
 | |
|       t = space();
 | |
|       if (if_block)
 | |
|         if_block.c();
 | |
|       attr(div, "class", "podcast-view svelte-unmvd4");
 | |
|     },
 | |
|     m(target, anchor) {
 | |
|       insert(target, div, anchor);
 | |
|       mount_component(topbar, div, null);
 | |
|       append(div, t);
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].m(div, null);
 | |
|       }
 | |
|       ctx[18](div);
 | |
|       current = true;
 | |
|     },
 | |
|     p(ctx2, [dirty]) {
 | |
|       const topbar_changes = {};
 | |
|       if (dirty & 64)
 | |
|         topbar_changes.canShowPlayer = !!ctx2[6];
 | |
|       if (!updating_viewState && dirty & 256) {
 | |
|         updating_viewState = true;
 | |
|         topbar_changes.viewState = ctx2[8];
 | |
|         add_flush_callback(() => updating_viewState = false);
 | |
|       }
 | |
|       topbar.$set(topbar_changes);
 | |
|       let previous_block_index = current_block_type_index;
 | |
|       current_block_type_index = select_block_type(ctx2, dirty);
 | |
|       if (current_block_type_index === previous_block_index) {
 | |
|         if (~current_block_type_index) {
 | |
|           if_blocks[current_block_type_index].p(ctx2, dirty);
 | |
|         }
 | |
|       } else {
 | |
|         if (if_block) {
 | |
|           group_outros();
 | |
|           transition_out(if_blocks[previous_block_index], 1, 1, () => {
 | |
|             if_blocks[previous_block_index] = null;
 | |
|           });
 | |
|           check_outros();
 | |
|         }
 | |
|         if (~current_block_type_index) {
 | |
|           if_block = if_blocks[current_block_type_index];
 | |
|           if (!if_block) {
 | |
|             if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
 | |
|             if_block.c();
 | |
|           } else {
 | |
|             if_block.p(ctx2, dirty);
 | |
|           }
 | |
|           transition_in(if_block, 1);
 | |
|           if_block.m(div, null);
 | |
|         } else {
 | |
|           if_block = null;
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     i(local) {
 | |
|       if (current)
 | |
|         return;
 | |
|       transition_in(topbar.$$.fragment, local);
 | |
|       transition_in(if_block);
 | |
|       current = true;
 | |
|     },
 | |
|     o(local) {
 | |
|       transition_out(topbar.$$.fragment, local);
 | |
|       transition_out(if_block);
 | |
|       current = false;
 | |
|     },
 | |
|     d(detaching) {
 | |
|       if (detaching)
 | |
|         detach(div);
 | |
|       destroy_component(topbar);
 | |
|       if (~current_block_type_index) {
 | |
|         if_blocks[current_block_type_index].d();
 | |
|       }
 | |
|       ctx[18](null);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function instance22($$self, $$props, $$invalidate) {
 | |
|   let $queue;
 | |
|   let $currentEpisode;
 | |
|   let $episodeCache;
 | |
|   let $downloadedEpisodes;
 | |
|   let $localFiles;
 | |
|   let $favorites;
 | |
|   let $podcastView;
 | |
|   let $viewState;
 | |
|   component_subscribe($$self, queue, ($$value) => $$invalidate(19, $queue = $$value));
 | |
|   component_subscribe($$self, currentEpisode, ($$value) => $$invalidate(6, $currentEpisode = $$value));
 | |
|   component_subscribe($$self, episodeCache, ($$value) => $$invalidate(20, $episodeCache = $$value));
 | |
|   component_subscribe($$self, downloadedEpisodes, ($$value) => $$invalidate(21, $downloadedEpisodes = $$value));
 | |
|   component_subscribe($$self, localFiles, ($$value) => $$invalidate(22, $localFiles = $$value));
 | |
|   component_subscribe($$self, favorites, ($$value) => $$invalidate(23, $favorites = $$value));
 | |
|   component_subscribe($$self, podcastView, ($$value) => $$invalidate(7, $podcastView = $$value));
 | |
|   component_subscribe($$self, viewState, ($$value) => $$invalidate(8, $viewState = $$value));
 | |
|   let feeds = [];
 | |
|   let selectedFeed = null;
 | |
|   let selectedPlaylist = null;
 | |
|   let displayedEpisodes = [];
 | |
|   let displayedPlaylists = [];
 | |
|   let latestEpisodes = [];
 | |
|   onMount(() => __awaiter(void 0, void 0, void 0, function* () {
 | |
|     const unsubscribePlaylists = playlists.subscribe((pl) => {
 | |
|       $$invalidate(4, displayedPlaylists = [$queue, $favorites, $localFiles, ...Object.values(pl)]);
 | |
|     });
 | |
|     const unsubscribeSavedFeeds = savedFeeds.subscribe((storeValue) => {
 | |
|       $$invalidate(0, feeds = Object.values(storeValue));
 | |
|     });
 | |
|     yield fetchEpisodesInAllFeeds(feeds);
 | |
|     const unsubscribeEpisodeCache = episodeCache.subscribe((cache) => {
 | |
|       $$invalidate(5, latestEpisodes = Object.entries(cache).map(([_, episodes]) => episodes.slice(0, 10)).flat().sort((a, b) => {
 | |
|         if (a.episodeDate && b.episodeDate)
 | |
|           return Number(b.episodeDate) - Number(a.episodeDate);
 | |
|         return 0;
 | |
|       }));
 | |
|     });
 | |
|     if (!selectedFeed) {
 | |
|       $$invalidate(3, displayedEpisodes = latestEpisodes);
 | |
|     }
 | |
|     return () => {
 | |
|       unsubscribeEpisodeCache();
 | |
|       unsubscribeSavedFeeds();
 | |
|       unsubscribePlaylists();
 | |
|     };
 | |
|   }));
 | |
|   function fetchEpisodes(feed, useCache = true) {
 | |
|     return __awaiter(this, void 0, void 0, function* () {
 | |
|       const cachedEpisodesInFeed = $episodeCache[feed.title];
 | |
|       if (useCache && cachedEpisodesInFeed && cachedEpisodesInFeed.length > 0) {
 | |
|         return cachedEpisodesInFeed;
 | |
|       }
 | |
|       try {
 | |
|         const episodes = yield new FeedParser(feed).getEpisodes(feed.url);
 | |
|         episodeCache.update((cache) => Object.assign(Object.assign({}, cache), { [feed.title]: episodes }));
 | |
|         return episodes;
 | |
|       } catch (error) {
 | |
|         return $downloadedEpisodes[feed.title];
 | |
|       }
 | |
|     });
 | |
|   }
 | |
|   function fetchEpisodesInAllFeeds(feedsToSearch) {
 | |
|     return Promise.all(feedsToSearch.map((feed) => fetchEpisodes(feed))).then((episodes) => {
 | |
|       return episodes.flat();
 | |
|     });
 | |
|   }
 | |
|   function handleClickPodcast(event) {
 | |
|     return __awaiter(this, void 0, void 0, function* () {
 | |
|       const { feed } = event.detail;
 | |
|       $$invalidate(3, displayedEpisodes = []);
 | |
|       $$invalidate(1, selectedFeed = feed);
 | |
|       $$invalidate(3, displayedEpisodes = yield fetchEpisodes(feed));
 | |
|       viewState.set(1 /* EpisodeList */);
 | |
|     });
 | |
|   }
 | |
|   function handleClickEpisode(event) {
 | |
|     const { episode } = event.detail;
 | |
|     currentEpisode.set(episode);
 | |
|     viewState.set(2 /* Player */);
 | |
|   }
 | |
|   function handleContextMenuEpisode({ detail: { event, episode } }) {
 | |
|     spawnEpisodeContextMenu(episode, event);
 | |
|   }
 | |
|   function handleClickRefresh() {
 | |
|     return __awaiter(this, void 0, void 0, function* () {
 | |
|       if (!selectedFeed)
 | |
|         return;
 | |
|       $$invalidate(3, displayedEpisodes = yield fetchEpisodes(selectedFeed, false));
 | |
|     });
 | |
|   }
 | |
|   const handleSearch = (0, import_obsidian18.debounce)((event) => {
 | |
|     const { query } = event.detail;
 | |
|     if (selectedFeed) {
 | |
|       const episodesInFeed = $episodeCache[selectedFeed.title];
 | |
|       $$invalidate(3, displayedEpisodes = searchEpisodes(query, episodesInFeed));
 | |
|       return;
 | |
|     }
 | |
|     $$invalidate(3, displayedEpisodes = searchEpisodes(query, latestEpisodes));
 | |
|   }, 250);
 | |
|   function handleClickPlaylist(event) {
 | |
|     const { event: clickEvent, playlist } = event.detail;
 | |
|     if (playlist.name === $queue.name && $queue.episodes.length > 0) {
 | |
|       if (!$currentEpisode) {
 | |
|         currentEpisode.set($queue.episodes[0]);
 | |
|       }
 | |
|       viewState.set(2 /* Player */);
 | |
|     } else {
 | |
|       $$invalidate(2, selectedPlaylist = playlist);
 | |
|       $$invalidate(3, displayedEpisodes = playlist.episodes);
 | |
|       viewState.set(1 /* EpisodeList */);
 | |
|     }
 | |
|   }
 | |
|   function topbar_viewState_binding(value) {
 | |
|     $viewState = value;
 | |
|     viewState.set($viewState);
 | |
|   }
 | |
|   const click_handler = () => {
 | |
|     $$invalidate(1, selectedFeed = null);
 | |
|     $$invalidate(3, displayedEpisodes = latestEpisodes);
 | |
|     viewState.set(1 /* EpisodeList */);
 | |
|   };
 | |
|   const click_handler_1 = () => {
 | |
|     $$invalidate(2, selectedPlaylist = null);
 | |
|     $$invalidate(3, displayedEpisodes = latestEpisodes);
 | |
|     viewState.set(1 /* EpisodeList */);
 | |
|   };
 | |
|   function div_binding($$value) {
 | |
|     binding_callbacks[$$value ? "unshift" : "push"](() => {
 | |
|       $podcastView = $$value;
 | |
|       podcastView.set($podcastView);
 | |
|     });
 | |
|   }
 | |
|   return [
 | |
|     feeds,
 | |
|     selectedFeed,
 | |
|     selectedPlaylist,
 | |
|     displayedEpisodes,
 | |
|     displayedPlaylists,
 | |
|     latestEpisodes,
 | |
|     $currentEpisode,
 | |
|     $podcastView,
 | |
|     $viewState,
 | |
|     handleClickPodcast,
 | |
|     handleClickEpisode,
 | |
|     handleContextMenuEpisode,
 | |
|     handleClickRefresh,
 | |
|     handleSearch,
 | |
|     handleClickPlaylist,
 | |
|     topbar_viewState_binding,
 | |
|     click_handler,
 | |
|     click_handler_1,
 | |
|     div_binding
 | |
|   ];
 | |
| }
 | |
| var PodcastView = class extends SvelteComponent {
 | |
|   constructor(options) {
 | |
|     super();
 | |
|     init(this, options, instance22, create_fragment23, safe_not_equal, {}, add_css17);
 | |
|   }
 | |
| };
 | |
| var PodcastView_default = PodcastView;
 | |
| 
 | |
| // src/ui/PodcastView/index.ts
 | |
| var MainView = class extends import_obsidian19.ItemView {
 | |
|   constructor(leaf, plugin2) {
 | |
|     super(leaf);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   getViewType() {
 | |
|     return VIEW_TYPE;
 | |
|   }
 | |
|   getDisplayText() {
 | |
|     return "Podcast Player";
 | |
|   }
 | |
|   getIcon() {
 | |
|     return "play-circle";
 | |
|   }
 | |
|   async onOpen() {
 | |
|     this.PodcastView = new PodcastView_default({
 | |
|       target: this.contentEl
 | |
|     });
 | |
|   }
 | |
|   async onClose() {
 | |
|     this.PodcastView?.$destroy();
 | |
|     this.contentEl.empty();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/types/StoreController.ts
 | |
| var StoreController = class {
 | |
|   constructor(store) {
 | |
|     this.store = store;
 | |
|   }
 | |
|   on() {
 | |
|     this.unsubscribe = this.store.subscribe(this.onChange.bind(this));
 | |
|     return this;
 | |
|   }
 | |
|   off() {
 | |
|     this.unsubscribe();
 | |
|     return this;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/EpisodeStatusController.ts
 | |
| var EpisodeStatusController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.playedEpisodes = value;
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/SavedFeedsController.ts
 | |
| var SavedFeedsController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.savedFeeds = value;
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/PlaylistController.ts
 | |
| var PlaylistController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.playlists = value;
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/QueueController.ts
 | |
| var QueueController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.queue = {
 | |
|       ...value,
 | |
|       ...QUEUE_SETTINGS
 | |
|     };
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
|   on() {
 | |
|     this.removeCurrentEpisodeFromQueue();
 | |
|     return super.on();
 | |
|   }
 | |
|   off() {
 | |
|     this.unsubscribeCurrentEpisode();
 | |
|     return super.off();
 | |
|   }
 | |
|   removeCurrentEpisodeFromQueue() {
 | |
|     this.unsubscribeCurrentEpisode = currentEpisode.subscribe((episode) => {
 | |
|       if (!episode)
 | |
|         return;
 | |
|       const queue2 = get_store_value(this.store);
 | |
|       const episodeIsInQueue = queue2.episodes.find((e) => e.title === episode.title);
 | |
|       this.store.update((playlist) => {
 | |
|         if (!episodeIsInQueue)
 | |
|           return playlist;
 | |
|         playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title);
 | |
|         return playlist;
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/FavoritesController.ts
 | |
| var FavoritesController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.favorites = {
 | |
|       ...value,
 | |
|       ...FAVORITES_SETTINGS
 | |
|     };
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/CurrentEpisodeController.ts
 | |
| var CurrentEpisodeController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.currentEpisode = value;
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/DownloadedEpisodesController.ts
 | |
| var DownloadedEpisodesController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.downloadedEpisodes = value;
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/store_controllers/LocalFilesController.ts
 | |
| var LocalFilesController = class extends StoreController {
 | |
|   constructor(store, plugin2) {
 | |
|     super(store);
 | |
|     this.plugin = plugin2;
 | |
|   }
 | |
|   onChange(value) {
 | |
|     this.plugin.settings.localFiles = {
 | |
|       ...value,
 | |
|       ...LOCAL_FILES_SETTINGS
 | |
|     };
 | |
|     this.plugin.saveSettings();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/URIHandler.ts
 | |
| var import_obsidian20 = require("obsidian");
 | |
| async function podNotesURIHandler({ url, episodeName, time }, api) {
 | |
|   if (!url || !episodeName || !time) {
 | |
|     new import_obsidian20.Notice("URL, episode name, and timestamp are required to play an episode");
 | |
|     return;
 | |
|   }
 | |
|   const decodedName = episodeName.replace(/\+/g, " ");
 | |
|   const currentEp = get_store_value(currentEpisode);
 | |
|   const episodeIsPlaying = currentEp?.title === decodedName;
 | |
|   if (episodeIsPlaying) {
 | |
|     viewState.set(2 /* Player */);
 | |
|     api.currentTime = parseFloat(time);
 | |
|     return;
 | |
|   }
 | |
|   const decodedUrl = url.replace(/\+/g, " ");
 | |
|   const localFile = app.vault.getAbstractFileByPath(decodedUrl);
 | |
|   let episode;
 | |
|   if (localFile) {
 | |
|     episode = localFiles.getLocalEpisode(decodedName);
 | |
|   } else {
 | |
|     const feedparser = new FeedParser();
 | |
|     episode = await feedparser.findItemByTitle(decodedName, url);
 | |
|   }
 | |
|   if (!episode) {
 | |
|     new import_obsidian20.Notice("Episode not found");
 | |
|     return;
 | |
|   }
 | |
|   currentEpisode.set(episode);
 | |
|   viewState.set(2 /* Player */);
 | |
|   new import_obsidian20.Notice("Episode found, playing now. Please click timestamp again to play at specific time.");
 | |
| }
 | |
| 
 | |
| // src/getContextMenuHandler.ts
 | |
| var import_obsidian21 = require("obsidian");
 | |
| function getContextMenuHandler() {
 | |
|   return this.app.workspace.on("file-menu", (menu, file) => {
 | |
|     if (!(file instanceof import_obsidian21.TFile))
 | |
|       return;
 | |
|     if (!file.extension.match(/mp3|mp4|wma|aac|wav|webm|aac|flac|m4a|/))
 | |
|       return;
 | |
|     menu.addItem((item) => item.setIcon("play").setTitle("Play with PodNotes").onClick(async () => {
 | |
|       const localEpisode = {
 | |
|         title: file.basename,
 | |
|         description: "",
 | |
|         content: "",
 | |
|         podcastName: "local file",
 | |
|         url: app.fileManager.generateMarkdownLink(file, ""),
 | |
|         streamUrl: await createMediaUrlObjectFromFilePath(file.path),
 | |
|         episodeDate: new Date(file.stat.ctime)
 | |
|       };
 | |
|       if (!downloadedEpisodes.isEpisodeDownloaded(localEpisode)) {
 | |
|         downloadedEpisodes.addEpisode(localEpisode, file.path, file.stat.size);
 | |
|         localFiles.addEpisode(localEpisode);
 | |
|       }
 | |
|       if (get_store_value(playedEpisodes)[file.basename]?.finished) {
 | |
|         playedEpisodes.markAsUnplayed(localEpisode);
 | |
|       }
 | |
|       currentEpisode.set(localEpisode);
 | |
|       viewState.set(2 /* Player */);
 | |
|     }));
 | |
|   });
 | |
| }
 | |
| 
 | |
| // src/getUniversalPodcastLink.ts
 | |
| var import_obsidian22 = require("obsidian");
 | |
| async function getUniversalPodcastLink(api) {
 | |
|   const { title, itunesTitle, podcastName, feedUrl } = api.podcast;
 | |
|   try {
 | |
|     const iTunesResponse = await queryiTunesPodcasts(api.podcast.podcastName);
 | |
|     const podcast = iTunesResponse.find((pod) => pod.title === podcastName && pod.url === feedUrl);
 | |
|     if (!podcast || !podcast.collectionId) {
 | |
|       throw new Error("Failed to get podcast from iTunes.");
 | |
|     }
 | |
|     const podLinkUrl = `https://pod.link/${podcast.collectionId}.json?limit=1000`;
 | |
|     const res = await (0, import_obsidian22.requestUrl)({
 | |
|       url: podLinkUrl
 | |
|     });
 | |
|     if (res.status !== 200) {
 | |
|       throw new Error(`Failed to get response from pod.link: ${podLinkUrl}`);
 | |
|     }
 | |
|     const targetTitle = itunesTitle ?? title;
 | |
|     const ep = res.json.episodes.find((episode) => episode.title === targetTitle);
 | |
|     if (!ep) {
 | |
|       throw new Error(`Failed to find episode "${targetTitle}" on pod.link. URL: ${podLinkUrl}`);
 | |
|     }
 | |
|     window.navigator.clipboard.writeText(`https://pod.link/${podcast.collectionId}/episode/${ep.episodeId}`);
 | |
|     new import_obsidian22.Notice("Universal episode link copied to clipboard.");
 | |
|   } catch (error) {
 | |
|     new import_obsidian22.Notice("Could not get podcast link.");
 | |
|     console.error(error);
 | |
|     return;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // src/services/TranscriptionService.ts
 | |
| var import_obsidian23 = require("obsidian");
 | |
| 
 | |
| // node_modules/openai/error.mjs
 | |
| var error_exports = {};
 | |
| __export(error_exports, {
 | |
|   APIConnectionError: () => APIConnectionError,
 | |
|   APIConnectionTimeoutError: () => APIConnectionTimeoutError,
 | |
|   APIError: () => APIError,
 | |
|   APIUserAbortError: () => APIUserAbortError,
 | |
|   AuthenticationError: () => AuthenticationError,
 | |
|   BadRequestError: () => BadRequestError,
 | |
|   ConflictError: () => ConflictError,
 | |
|   InternalServerError: () => InternalServerError,
 | |
|   NotFoundError: () => NotFoundError,
 | |
|   OpenAIError: () => OpenAIError,
 | |
|   PermissionDeniedError: () => PermissionDeniedError,
 | |
|   RateLimitError: () => RateLimitError,
 | |
|   UnprocessableEntityError: () => UnprocessableEntityError
 | |
| });
 | |
| 
 | |
| // node_modules/openai/version.mjs
 | |
| var VERSION = "4.52.7";
 | |
| 
 | |
| // node_modules/openai/_shims/registry.mjs
 | |
| var auto = false;
 | |
| var kind = void 0;
 | |
| var fetch2 = void 0;
 | |
| var Request2 = void 0;
 | |
| var Response2 = void 0;
 | |
| var Headers2 = void 0;
 | |
| var FormData2 = void 0;
 | |
| var Blob2 = void 0;
 | |
| var File2 = void 0;
 | |
| var ReadableStream2 = void 0;
 | |
| var getMultipartRequestOptions = void 0;
 | |
| var getDefaultAgent = void 0;
 | |
| var fileFromPath = void 0;
 | |
| var isFsReadStream = void 0;
 | |
| function setShims(shims, options = { auto: false }) {
 | |
|   if (auto) {
 | |
|     throw new Error(`you must \`import 'openai/shims/${shims.kind}'\` before importing anything else from openai`);
 | |
|   }
 | |
|   if (kind) {
 | |
|     throw new Error(`can't \`import 'openai/shims/${shims.kind}'\` after \`import 'openai/shims/${kind}'\``);
 | |
|   }
 | |
|   auto = options.auto;
 | |
|   kind = shims.kind;
 | |
|   fetch2 = shims.fetch;
 | |
|   Request2 = shims.Request;
 | |
|   Response2 = shims.Response;
 | |
|   Headers2 = shims.Headers;
 | |
|   FormData2 = shims.FormData;
 | |
|   Blob2 = shims.Blob;
 | |
|   File2 = shims.File;
 | |
|   ReadableStream2 = shims.ReadableStream;
 | |
|   getMultipartRequestOptions = shims.getMultipartRequestOptions;
 | |
|   getDefaultAgent = shims.getDefaultAgent;
 | |
|   fileFromPath = shims.fileFromPath;
 | |
|   isFsReadStream = shims.isFsReadStream;
 | |
| }
 | |
| 
 | |
| // node_modules/openai/_shims/MultipartBody.mjs
 | |
| var MultipartBody = class {
 | |
|   constructor(body) {
 | |
|     this.body = body;
 | |
|   }
 | |
|   get [Symbol.toStringTag]() {
 | |
|     return "MultipartBody";
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/_shims/web-runtime.mjs
 | |
| function getRuntime({ manuallyImported } = {}) {
 | |
|   const recommendation = manuallyImported ? `You may need to use polyfills` : `Add one of these imports before your first \`import \u2026 from 'openai'\`:
 | |
| - \`import 'openai/shims/node'\` (if you're running on Node)
 | |
| - \`import 'openai/shims/web'\` (otherwise)
 | |
| `;
 | |
|   let _fetch, _Request, _Response, _Headers;
 | |
|   try {
 | |
|     _fetch = fetch;
 | |
|     _Request = Request;
 | |
|     _Response = Response;
 | |
|     _Headers = Headers;
 | |
|   } catch (error) {
 | |
|     throw new Error(`this environment is missing the following Web Fetch API type: ${error.message}. ${recommendation}`);
 | |
|   }
 | |
|   return {
 | |
|     kind: "web",
 | |
|     fetch: _fetch,
 | |
|     Request: _Request,
 | |
|     Response: _Response,
 | |
|     Headers: _Headers,
 | |
|     FormData: typeof FormData !== "undefined" ? FormData : class FormData {
 | |
|       constructor() {
 | |
|         throw new Error(`file uploads aren't supported in this environment yet as 'FormData' is undefined. ${recommendation}`);
 | |
|       }
 | |
|     },
 | |
|     Blob: typeof Blob !== "undefined" ? Blob : class Blob {
 | |
|       constructor() {
 | |
|         throw new Error(`file uploads aren't supported in this environment yet as 'Blob' is undefined. ${recommendation}`);
 | |
|       }
 | |
|     },
 | |
|     File: typeof File !== "undefined" ? File : class File {
 | |
|       constructor() {
 | |
|         throw new Error(`file uploads aren't supported in this environment yet as 'File' is undefined. ${recommendation}`);
 | |
|       }
 | |
|     },
 | |
|     ReadableStream: typeof ReadableStream !== "undefined" ? ReadableStream : class ReadableStream {
 | |
|       constructor() {
 | |
|         throw new Error(`streaming isn't supported in this environment yet as 'ReadableStream' is undefined. ${recommendation}`);
 | |
|       }
 | |
|     },
 | |
|     getMultipartRequestOptions: async (form, opts) => ({
 | |
|       ...opts,
 | |
|       body: new MultipartBody(form)
 | |
|     }),
 | |
|     getDefaultAgent: (url) => void 0,
 | |
|     fileFromPath: () => {
 | |
|       throw new Error("The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/openai/openai-node#file-uploads");
 | |
|     },
 | |
|     isFsReadStream: (value) => false
 | |
|   };
 | |
| }
 | |
| 
 | |
| // node_modules/openai/_shims/index.mjs
 | |
| if (!kind)
 | |
|   setShims(getRuntime(), { auto: true });
 | |
| 
 | |
| // node_modules/openai/streaming.mjs
 | |
| var Stream = class {
 | |
|   constructor(iterator, controller) {
 | |
|     this.iterator = iterator;
 | |
|     this.controller = controller;
 | |
|   }
 | |
|   static fromSSEResponse(response, controller) {
 | |
|     let consumed = false;
 | |
|     async function* iterator() {
 | |
|       if (consumed) {
 | |
|         throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
 | |
|       }
 | |
|       consumed = true;
 | |
|       let done = false;
 | |
|       try {
 | |
|         for await (const sse of _iterSSEMessages(response, controller)) {
 | |
|           if (done)
 | |
|             continue;
 | |
|           if (sse.data.startsWith("[DONE]")) {
 | |
|             done = true;
 | |
|             continue;
 | |
|           }
 | |
|           if (sse.event === null) {
 | |
|             let data;
 | |
|             try {
 | |
|               data = JSON.parse(sse.data);
 | |
|             } catch (e) {
 | |
|               console.error(`Could not parse message into JSON:`, sse.data);
 | |
|               console.error(`From chunk:`, sse.raw);
 | |
|               throw e;
 | |
|             }
 | |
|             if (data && data.error) {
 | |
|               throw new APIError(void 0, data.error, void 0, void 0);
 | |
|             }
 | |
|             yield data;
 | |
|           } else {
 | |
|             let data;
 | |
|             try {
 | |
|               data = JSON.parse(sse.data);
 | |
|             } catch (e) {
 | |
|               console.error(`Could not parse message into JSON:`, sse.data);
 | |
|               console.error(`From chunk:`, sse.raw);
 | |
|               throw e;
 | |
|             }
 | |
|             if (sse.event == "error") {
 | |
|               throw new APIError(void 0, data.error, data.message, void 0);
 | |
|             }
 | |
|             yield { event: sse.event, data };
 | |
|           }
 | |
|         }
 | |
|         done = true;
 | |
|       } catch (e) {
 | |
|         if (e instanceof Error && e.name === "AbortError")
 | |
|           return;
 | |
|         throw e;
 | |
|       } finally {
 | |
|         if (!done)
 | |
|           controller.abort();
 | |
|       }
 | |
|     }
 | |
|     return new Stream(iterator, controller);
 | |
|   }
 | |
|   static fromReadableStream(readableStream, controller) {
 | |
|     let consumed = false;
 | |
|     async function* iterLines() {
 | |
|       const lineDecoder = new LineDecoder();
 | |
|       const iter = readableStreamAsyncIterable(readableStream);
 | |
|       for await (const chunk of iter) {
 | |
|         for (const line of lineDecoder.decode(chunk)) {
 | |
|           yield line;
 | |
|         }
 | |
|       }
 | |
|       for (const line of lineDecoder.flush()) {
 | |
|         yield line;
 | |
|       }
 | |
|     }
 | |
|     async function* iterator() {
 | |
|       if (consumed) {
 | |
|         throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
 | |
|       }
 | |
|       consumed = true;
 | |
|       let done = false;
 | |
|       try {
 | |
|         for await (const line of iterLines()) {
 | |
|           if (done)
 | |
|             continue;
 | |
|           if (line)
 | |
|             yield JSON.parse(line);
 | |
|         }
 | |
|         done = true;
 | |
|       } catch (e) {
 | |
|         if (e instanceof Error && e.name === "AbortError")
 | |
|           return;
 | |
|         throw e;
 | |
|       } finally {
 | |
|         if (!done)
 | |
|           controller.abort();
 | |
|       }
 | |
|     }
 | |
|     return new Stream(iterator, controller);
 | |
|   }
 | |
|   [Symbol.asyncIterator]() {
 | |
|     return this.iterator();
 | |
|   }
 | |
|   tee() {
 | |
|     const left = [];
 | |
|     const right = [];
 | |
|     const iterator = this.iterator();
 | |
|     const teeIterator = (queue2) => {
 | |
|       return {
 | |
|         next: () => {
 | |
|           if (queue2.length === 0) {
 | |
|             const result = iterator.next();
 | |
|             left.push(result);
 | |
|             right.push(result);
 | |
|           }
 | |
|           return queue2.shift();
 | |
|         }
 | |
|       };
 | |
|     };
 | |
|     return [
 | |
|       new Stream(() => teeIterator(left), this.controller),
 | |
|       new Stream(() => teeIterator(right), this.controller)
 | |
|     ];
 | |
|   }
 | |
|   toReadableStream() {
 | |
|     const self2 = this;
 | |
|     let iter;
 | |
|     const encoder = new TextEncoder();
 | |
|     return new ReadableStream2({
 | |
|       async start() {
 | |
|         iter = self2[Symbol.asyncIterator]();
 | |
|       },
 | |
|       async pull(ctrl) {
 | |
|         try {
 | |
|           const { value, done } = await iter.next();
 | |
|           if (done)
 | |
|             return ctrl.close();
 | |
|           const bytes = encoder.encode(JSON.stringify(value) + "\n");
 | |
|           ctrl.enqueue(bytes);
 | |
|         } catch (err) {
 | |
|           ctrl.error(err);
 | |
|         }
 | |
|       },
 | |
|       async cancel() {
 | |
|         await iter.return?.();
 | |
|       }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| async function* _iterSSEMessages(response, controller) {
 | |
|   if (!response.body) {
 | |
|     controller.abort();
 | |
|     throw new OpenAIError(`Attempted to iterate over a response with no body`);
 | |
|   }
 | |
|   const sseDecoder = new SSEDecoder();
 | |
|   const lineDecoder = new LineDecoder();
 | |
|   const iter = readableStreamAsyncIterable(response.body);
 | |
|   for await (const sseChunk of iterSSEChunks(iter)) {
 | |
|     for (const line of lineDecoder.decode(sseChunk)) {
 | |
|       const sse = sseDecoder.decode(line);
 | |
|       if (sse)
 | |
|         yield sse;
 | |
|     }
 | |
|   }
 | |
|   for (const line of lineDecoder.flush()) {
 | |
|     const sse = sseDecoder.decode(line);
 | |
|     if (sse)
 | |
|       yield sse;
 | |
|   }
 | |
| }
 | |
| async function* iterSSEChunks(iterator) {
 | |
|   let data = new Uint8Array();
 | |
|   for await (const chunk of iterator) {
 | |
|     if (chunk == null) {
 | |
|       continue;
 | |
|     }
 | |
|     const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk;
 | |
|     let newData = new Uint8Array(data.length + binaryChunk.length);
 | |
|     newData.set(data);
 | |
|     newData.set(binaryChunk, data.length);
 | |
|     data = newData;
 | |
|     let patternIndex;
 | |
|     while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
 | |
|       yield data.slice(0, patternIndex);
 | |
|       data = data.slice(patternIndex);
 | |
|     }
 | |
|   }
 | |
|   if (data.length > 0) {
 | |
|     yield data;
 | |
|   }
 | |
| }
 | |
| function findDoubleNewlineIndex(buffer) {
 | |
|   const newline = 10;
 | |
|   const carriage = 13;
 | |
|   for (let i = 0; i < buffer.length - 2; i++) {
 | |
|     if (buffer[i] === newline && buffer[i + 1] === newline) {
 | |
|       return i + 2;
 | |
|     }
 | |
|     if (buffer[i] === carriage && buffer[i + 1] === carriage) {
 | |
|       return i + 2;
 | |
|     }
 | |
|     if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) {
 | |
|       return i + 4;
 | |
|     }
 | |
|   }
 | |
|   return -1;
 | |
| }
 | |
| var SSEDecoder = class {
 | |
|   constructor() {
 | |
|     this.event = null;
 | |
|     this.data = [];
 | |
|     this.chunks = [];
 | |
|   }
 | |
|   decode(line) {
 | |
|     if (line.endsWith("\r")) {
 | |
|       line = line.substring(0, line.length - 1);
 | |
|     }
 | |
|     if (!line) {
 | |
|       if (!this.event && !this.data.length)
 | |
|         return null;
 | |
|       const sse = {
 | |
|         event: this.event,
 | |
|         data: this.data.join("\n"),
 | |
|         raw: this.chunks
 | |
|       };
 | |
|       this.event = null;
 | |
|       this.data = [];
 | |
|       this.chunks = [];
 | |
|       return sse;
 | |
|     }
 | |
|     this.chunks.push(line);
 | |
|     if (line.startsWith(":")) {
 | |
|       return null;
 | |
|     }
 | |
|     let [fieldname, _, value] = partition(line, ":");
 | |
|     if (value.startsWith(" ")) {
 | |
|       value = value.substring(1);
 | |
|     }
 | |
|     if (fieldname === "event") {
 | |
|       this.event = value;
 | |
|     } else if (fieldname === "data") {
 | |
|       this.data.push(value);
 | |
|     }
 | |
|     return null;
 | |
|   }
 | |
| };
 | |
| var LineDecoder = class {
 | |
|   constructor() {
 | |
|     this.buffer = [];
 | |
|     this.trailingCR = false;
 | |
|   }
 | |
|   decode(chunk) {
 | |
|     let text2 = this.decodeText(chunk);
 | |
|     if (this.trailingCR) {
 | |
|       text2 = "\r" + text2;
 | |
|       this.trailingCR = false;
 | |
|     }
 | |
|     if (text2.endsWith("\r")) {
 | |
|       this.trailingCR = true;
 | |
|       text2 = text2.slice(0, -1);
 | |
|     }
 | |
|     if (!text2) {
 | |
|       return [];
 | |
|     }
 | |
|     const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text2[text2.length - 1] || "");
 | |
|     let lines = text2.split(LineDecoder.NEWLINE_REGEXP);
 | |
|     if (trailingNewline) {
 | |
|       lines.pop();
 | |
|     }
 | |
|     if (lines.length === 1 && !trailingNewline) {
 | |
|       this.buffer.push(lines[0]);
 | |
|       return [];
 | |
|     }
 | |
|     if (this.buffer.length > 0) {
 | |
|       lines = [this.buffer.join("") + lines[0], ...lines.slice(1)];
 | |
|       this.buffer = [];
 | |
|     }
 | |
|     if (!trailingNewline) {
 | |
|       this.buffer = [lines.pop() || ""];
 | |
|     }
 | |
|     return lines;
 | |
|   }
 | |
|   decodeText(bytes) {
 | |
|     if (bytes == null)
 | |
|       return "";
 | |
|     if (typeof bytes === "string")
 | |
|       return bytes;
 | |
|     if (typeof Buffer !== "undefined") {
 | |
|       if (bytes instanceof Buffer) {
 | |
|         return bytes.toString();
 | |
|       }
 | |
|       if (bytes instanceof Uint8Array) {
 | |
|         return Buffer.from(bytes).toString();
 | |
|       }
 | |
|       throw new OpenAIError(`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`);
 | |
|     }
 | |
|     if (typeof TextDecoder !== "undefined") {
 | |
|       if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
 | |
|         this.textDecoder ?? (this.textDecoder = new TextDecoder("utf8"));
 | |
|         return this.textDecoder.decode(bytes);
 | |
|       }
 | |
|       throw new OpenAIError(`Unexpected: received non-Uint8Array/ArrayBuffer (${bytes.constructor.name}) in a web platform. Please report this error.`);
 | |
|     }
 | |
|     throw new OpenAIError(`Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`);
 | |
|   }
 | |
|   flush() {
 | |
|     if (!this.buffer.length && !this.trailingCR) {
 | |
|       return [];
 | |
|     }
 | |
|     const lines = [this.buffer.join("")];
 | |
|     this.buffer = [];
 | |
|     this.trailingCR = false;
 | |
|     return lines;
 | |
|   }
 | |
| };
 | |
| LineDecoder.NEWLINE_CHARS = /* @__PURE__ */ new Set(["\n", "\r"]);
 | |
| LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
 | |
| function partition(str2, delimiter) {
 | |
|   const index = str2.indexOf(delimiter);
 | |
|   if (index !== -1) {
 | |
|     return [str2.substring(0, index), delimiter, str2.substring(index + delimiter.length)];
 | |
|   }
 | |
|   return [str2, "", ""];
 | |
| }
 | |
| function readableStreamAsyncIterable(stream) {
 | |
|   if (stream[Symbol.asyncIterator])
 | |
|     return stream;
 | |
|   const reader = stream.getReader();
 | |
|   return {
 | |
|     async next() {
 | |
|       try {
 | |
|         const result = await reader.read();
 | |
|         if (result?.done)
 | |
|           reader.releaseLock();
 | |
|         return result;
 | |
|       } catch (e) {
 | |
|         reader.releaseLock();
 | |
|         throw e;
 | |
|       }
 | |
|     },
 | |
|     async return() {
 | |
|       const cancelPromise = reader.cancel();
 | |
|       reader.releaseLock();
 | |
|       await cancelPromise;
 | |
|       return { done: true, value: void 0 };
 | |
|     },
 | |
|     [Symbol.asyncIterator]() {
 | |
|       return this;
 | |
|     }
 | |
|   };
 | |
| }
 | |
| 
 | |
| // node_modules/openai/uploads.mjs
 | |
| var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function";
 | |
| var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value);
 | |
| var isBlobLike = (value) => value != null && typeof value === "object" && typeof value.size === "number" && typeof value.type === "string" && typeof value.text === "function" && typeof value.slice === "function" && typeof value.arrayBuffer === "function";
 | |
| var isUploadable = (value) => {
 | |
|   return isFileLike(value) || isResponseLike(value) || isFsReadStream(value);
 | |
| };
 | |
| async function toFile(value, name, options) {
 | |
|   value = await value;
 | |
|   options ?? (options = isFileLike(value) ? { lastModified: value.lastModified, type: value.type } : {});
 | |
|   if (isResponseLike(value)) {
 | |
|     const blob = await value.blob();
 | |
|     name || (name = new URL(value.url).pathname.split(/[\\/]/).pop() ?? "unknown_file");
 | |
|     return new File2([blob], name, options);
 | |
|   }
 | |
|   const bits = await getBytes(value);
 | |
|   name || (name = getName(value) ?? "unknown_file");
 | |
|   if (!options.type) {
 | |
|     const type = bits[0]?.type;
 | |
|     if (typeof type === "string") {
 | |
|       options = { ...options, type };
 | |
|     }
 | |
|   }
 | |
|   return new File2(bits, name, options);
 | |
| }
 | |
| async function getBytes(value) {
 | |
|   let parts = [];
 | |
|   if (typeof value === "string" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
 | |
|     parts.push(value);
 | |
|   } else if (isBlobLike(value)) {
 | |
|     parts.push(await value.arrayBuffer());
 | |
|   } else if (isAsyncIterableIterator(value)) {
 | |
|     for await (const chunk of value) {
 | |
|       parts.push(chunk);
 | |
|     }
 | |
|   } else {
 | |
|     throw new Error(`Unexpected data type: ${typeof value}; constructor: ${value?.constructor?.name}; props: ${propsForError(value)}`);
 | |
|   }
 | |
|   return parts;
 | |
| }
 | |
| function propsForError(value) {
 | |
|   const props = Object.getOwnPropertyNames(value);
 | |
|   return `[${props.map((p) => `"${p}"`).join(", ")}]`;
 | |
| }
 | |
| function getName(value) {
 | |
|   return getStringFromMaybeBuffer(value.name) || getStringFromMaybeBuffer(value.filename) || getStringFromMaybeBuffer(value.path)?.split(/[\\/]/).pop();
 | |
| }
 | |
| var getStringFromMaybeBuffer = (x) => {
 | |
|   if (typeof x === "string")
 | |
|     return x;
 | |
|   if (typeof Buffer !== "undefined" && x instanceof Buffer)
 | |
|     return String(x);
 | |
|   return void 0;
 | |
| };
 | |
| var isAsyncIterableIterator = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
 | |
| var isMultipartBody = (body) => body && typeof body === "object" && body.body && body[Symbol.toStringTag] === "MultipartBody";
 | |
| var multipartFormRequestOptions = async (opts) => {
 | |
|   const form = await createForm(opts.body);
 | |
|   return getMultipartRequestOptions(form, opts);
 | |
| };
 | |
| var createForm = async (body) => {
 | |
|   const form = new FormData2();
 | |
|   await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value)));
 | |
|   return form;
 | |
| };
 | |
| var addFormValue = async (form, key, value) => {
 | |
|   if (value === void 0)
 | |
|     return;
 | |
|   if (value == null) {
 | |
|     throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`);
 | |
|   }
 | |
|   if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
 | |
|     form.append(key, String(value));
 | |
|   } else if (isUploadable(value)) {
 | |
|     const file = await toFile(value);
 | |
|     form.append(key, file);
 | |
|   } else if (Array.isArray(value)) {
 | |
|     await Promise.all(value.map((entry) => addFormValue(form, key + "[]", entry)));
 | |
|   } else if (typeof value === "object") {
 | |
|     await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)));
 | |
|   } else {
 | |
|     throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`);
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/core.mjs
 | |
| var __classPrivateFieldSet2 = function(receiver, state, value, kind2, f) {
 | |
|   if (kind2 === "m")
 | |
|     throw new TypeError("Private method is not writable");
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a setter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|   return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
| };
 | |
| var __classPrivateFieldGet2 = function(receiver, state, kind2, f) {
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a getter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|   return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
| };
 | |
| var _AbstractPage_client;
 | |
| async function defaultParseResponse(props) {
 | |
|   const { response } = props;
 | |
|   if (props.options.stream) {
 | |
|     debug("response", response.status, response.url, response.headers, response.body);
 | |
|     if (props.options.__streamClass) {
 | |
|       return props.options.__streamClass.fromSSEResponse(response, props.controller);
 | |
|     }
 | |
|     return Stream.fromSSEResponse(response, props.controller);
 | |
|   }
 | |
|   if (response.status === 204) {
 | |
|     return null;
 | |
|   }
 | |
|   if (props.options.__binaryResponse) {
 | |
|     return response;
 | |
|   }
 | |
|   const contentType = response.headers.get("content-type");
 | |
|   const isJSON = contentType?.includes("application/json") || contentType?.includes("application/vnd.api+json");
 | |
|   if (isJSON) {
 | |
|     const json = await response.json();
 | |
|     debug("response", response.status, response.url, response.headers, json);
 | |
|     return json;
 | |
|   }
 | |
|   const text2 = await response.text();
 | |
|   debug("response", response.status, response.url, response.headers, text2);
 | |
|   return text2;
 | |
| }
 | |
| var APIPromise = class extends Promise {
 | |
|   constructor(responsePromise, parseResponse = defaultParseResponse) {
 | |
|     super((resolve) => {
 | |
|       resolve(null);
 | |
|     });
 | |
|     this.responsePromise = responsePromise;
 | |
|     this.parseResponse = parseResponse;
 | |
|   }
 | |
|   _thenUnwrap(transform) {
 | |
|     return new APIPromise(this.responsePromise, async (props) => transform(await this.parseResponse(props)));
 | |
|   }
 | |
|   asResponse() {
 | |
|     return this.responsePromise.then((p) => p.response);
 | |
|   }
 | |
|   async withResponse() {
 | |
|     const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
 | |
|     return { data, response };
 | |
|   }
 | |
|   parse() {
 | |
|     if (!this.parsedPromise) {
 | |
|       this.parsedPromise = this.responsePromise.then(this.parseResponse);
 | |
|     }
 | |
|     return this.parsedPromise;
 | |
|   }
 | |
|   then(onfulfilled, onrejected) {
 | |
|     return this.parse().then(onfulfilled, onrejected);
 | |
|   }
 | |
|   catch(onrejected) {
 | |
|     return this.parse().catch(onrejected);
 | |
|   }
 | |
|   finally(onfinally) {
 | |
|     return this.parse().finally(onfinally);
 | |
|   }
 | |
| };
 | |
| var APIClient = class {
 | |
|   constructor({
 | |
|     baseURL,
 | |
|     maxRetries = 2,
 | |
|     timeout = 6e5,
 | |
|     httpAgent,
 | |
|     fetch: overridenFetch
 | |
|   }) {
 | |
|     this.baseURL = baseURL;
 | |
|     this.maxRetries = validatePositiveInteger("maxRetries", maxRetries);
 | |
|     this.timeout = validatePositiveInteger("timeout", timeout);
 | |
|     this.httpAgent = httpAgent;
 | |
|     this.fetch = overridenFetch ?? fetch2;
 | |
|   }
 | |
|   authHeaders(opts) {
 | |
|     return {};
 | |
|   }
 | |
|   defaultHeaders(opts) {
 | |
|     return {
 | |
|       Accept: "application/json",
 | |
|       "Content-Type": "application/json",
 | |
|       "User-Agent": this.getUserAgent(),
 | |
|       ...getPlatformHeaders(),
 | |
|       ...this.authHeaders(opts)
 | |
|     };
 | |
|   }
 | |
|   validateHeaders(headers, customHeaders) {
 | |
|   }
 | |
|   defaultIdempotencyKey() {
 | |
|     return `stainless-node-retry-${uuid4()}`;
 | |
|   }
 | |
|   get(path, opts) {
 | |
|     return this.methodRequest("get", path, opts);
 | |
|   }
 | |
|   post(path, opts) {
 | |
|     return this.methodRequest("post", path, opts);
 | |
|   }
 | |
|   patch(path, opts) {
 | |
|     return this.methodRequest("patch", path, opts);
 | |
|   }
 | |
|   put(path, opts) {
 | |
|     return this.methodRequest("put", path, opts);
 | |
|   }
 | |
|   delete(path, opts) {
 | |
|     return this.methodRequest("delete", path, opts);
 | |
|   }
 | |
|   methodRequest(method, path, opts) {
 | |
|     return this.request(Promise.resolve(opts).then(async (opts2) => {
 | |
|       const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
 | |
|       return { method, path, ...opts2, body };
 | |
|     }));
 | |
|   }
 | |
|   getAPIList(path, Page2, opts) {
 | |
|     return this.requestAPIList(Page2, { method: "get", path, ...opts });
 | |
|   }
 | |
|   calculateContentLength(body) {
 | |
|     if (typeof body === "string") {
 | |
|       if (typeof Buffer !== "undefined") {
 | |
|         return Buffer.byteLength(body, "utf8").toString();
 | |
|       }
 | |
|       if (typeof TextEncoder !== "undefined") {
 | |
|         const encoder = new TextEncoder();
 | |
|         const encoded = encoder.encode(body);
 | |
|         return encoded.length.toString();
 | |
|       }
 | |
|     } else if (ArrayBuffer.isView(body)) {
 | |
|       return body.byteLength.toString();
 | |
|     }
 | |
|     return null;
 | |
|   }
 | |
|   buildRequest(options) {
 | |
|     const { method, path, query, headers = {} } = options;
 | |
|     const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
 | |
|     const contentLength = this.calculateContentLength(body);
 | |
|     const url = this.buildURL(path, query);
 | |
|     if ("timeout" in options)
 | |
|       validatePositiveInteger("timeout", options.timeout);
 | |
|     const timeout = options.timeout ?? this.timeout;
 | |
|     const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url);
 | |
|     const minAgentTimeout = timeout + 1e3;
 | |
|     if (typeof httpAgent?.options?.timeout === "number" && minAgentTimeout > (httpAgent.options.timeout ?? 0)) {
 | |
|       httpAgent.options.timeout = minAgentTimeout;
 | |
|     }
 | |
|     if (this.idempotencyHeader && method !== "get") {
 | |
|       if (!options.idempotencyKey)
 | |
|         options.idempotencyKey = this.defaultIdempotencyKey();
 | |
|       headers[this.idempotencyHeader] = options.idempotencyKey;
 | |
|     }
 | |
|     const reqHeaders = this.buildHeaders({ options, headers, contentLength });
 | |
|     const req = {
 | |
|       method,
 | |
|       ...body && { body },
 | |
|       headers: reqHeaders,
 | |
|       ...httpAgent && { agent: httpAgent },
 | |
|       signal: options.signal ?? null
 | |
|     };
 | |
|     return { req, url, timeout };
 | |
|   }
 | |
|   buildHeaders({ options, headers, contentLength }) {
 | |
|     const reqHeaders = {};
 | |
|     if (contentLength) {
 | |
|       reqHeaders["content-length"] = contentLength;
 | |
|     }
 | |
|     const defaultHeaders = this.defaultHeaders(options);
 | |
|     applyHeadersMut(reqHeaders, defaultHeaders);
 | |
|     applyHeadersMut(reqHeaders, headers);
 | |
|     if (isMultipartBody(options.body) && kind !== "node") {
 | |
|       delete reqHeaders["content-type"];
 | |
|     }
 | |
|     this.validateHeaders(reqHeaders, headers);
 | |
|     return reqHeaders;
 | |
|   }
 | |
|   async prepareOptions(options) {
 | |
|   }
 | |
|   async prepareRequest(request, { url, options }) {
 | |
|   }
 | |
|   parseHeaders(headers) {
 | |
|     return !headers ? {} : Symbol.iterator in headers ? Object.fromEntries(Array.from(headers).map((header) => [...header])) : { ...headers };
 | |
|   }
 | |
|   makeStatusError(status, error, message, headers) {
 | |
|     return APIError.generate(status, error, message, headers);
 | |
|   }
 | |
|   request(options, remainingRetries = null) {
 | |
|     return new APIPromise(this.makeRequest(options, remainingRetries));
 | |
|   }
 | |
|   async makeRequest(optionsInput, retriesRemaining) {
 | |
|     const options = await optionsInput;
 | |
|     if (retriesRemaining == null) {
 | |
|       retriesRemaining = options.maxRetries ?? this.maxRetries;
 | |
|     }
 | |
|     await this.prepareOptions(options);
 | |
|     const { req, url, timeout } = this.buildRequest(options);
 | |
|     await this.prepareRequest(req, { url, options });
 | |
|     debug("request", url, options, req.headers);
 | |
|     if (options.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     const controller = new AbortController();
 | |
|     const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
 | |
|     if (response instanceof Error) {
 | |
|       if (options.signal?.aborted) {
 | |
|         throw new APIUserAbortError();
 | |
|       }
 | |
|       if (retriesRemaining) {
 | |
|         return this.retryRequest(options, retriesRemaining);
 | |
|       }
 | |
|       if (response.name === "AbortError") {
 | |
|         throw new APIConnectionTimeoutError();
 | |
|       }
 | |
|       throw new APIConnectionError({ cause: response });
 | |
|     }
 | |
|     const responseHeaders = createResponseHeaders(response.headers);
 | |
|     if (!response.ok) {
 | |
|       if (retriesRemaining && this.shouldRetry(response)) {
 | |
|         const retryMessage2 = `retrying, ${retriesRemaining} attempts remaining`;
 | |
|         debug(`response (error; ${retryMessage2})`, response.status, url, responseHeaders);
 | |
|         return this.retryRequest(options, retriesRemaining, responseHeaders);
 | |
|       }
 | |
|       const errText = await response.text().catch((e) => castToError(e).message);
 | |
|       const errJSON = safeJSON(errText);
 | |
|       const errMessage = errJSON ? void 0 : errText;
 | |
|       const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`;
 | |
|       debug(`response (error; ${retryMessage})`, response.status, url, responseHeaders, errMessage);
 | |
|       const err = this.makeStatusError(response.status, errJSON, errMessage, responseHeaders);
 | |
|       throw err;
 | |
|     }
 | |
|     return { response, options, controller };
 | |
|   }
 | |
|   requestAPIList(Page2, options) {
 | |
|     const request = this.makeRequest(options, null);
 | |
|     return new PagePromise(this, request, Page2);
 | |
|   }
 | |
|   buildURL(path, query) {
 | |
|     const url = isAbsoluteURL(path) ? new URL(path) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path.startsWith("/") ? path.slice(1) : path));
 | |
|     const defaultQuery = this.defaultQuery();
 | |
|     if (!isEmptyObj(defaultQuery)) {
 | |
|       query = { ...defaultQuery, ...query };
 | |
|     }
 | |
|     if (typeof query === "object" && query && !Array.isArray(query)) {
 | |
|       url.search = this.stringifyQuery(query);
 | |
|     }
 | |
|     return url.toString();
 | |
|   }
 | |
|   stringifyQuery(query) {
 | |
|     return Object.entries(query).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => {
 | |
|       if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
 | |
|         return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
 | |
|       }
 | |
|       if (value === null) {
 | |
|         return `${encodeURIComponent(key)}=`;
 | |
|       }
 | |
|       throw new OpenAIError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
 | |
|     }).join("&");
 | |
|   }
 | |
|   async fetchWithTimeout(url, init2, ms, controller) {
 | |
|     const { signal, ...options } = init2 || {};
 | |
|     if (signal)
 | |
|       signal.addEventListener("abort", () => controller.abort());
 | |
|     const timeout = setTimeout(() => controller.abort(), ms);
 | |
|     return this.getRequestClient().fetch.call(void 0, url, { signal: controller.signal, ...options }).finally(() => {
 | |
|       clearTimeout(timeout);
 | |
|     });
 | |
|   }
 | |
|   getRequestClient() {
 | |
|     return { fetch: this.fetch };
 | |
|   }
 | |
|   shouldRetry(response) {
 | |
|     const shouldRetryHeader = response.headers.get("x-should-retry");
 | |
|     if (shouldRetryHeader === "true")
 | |
|       return true;
 | |
|     if (shouldRetryHeader === "false")
 | |
|       return false;
 | |
|     if (response.status === 408)
 | |
|       return true;
 | |
|     if (response.status === 409)
 | |
|       return true;
 | |
|     if (response.status === 429)
 | |
|       return true;
 | |
|     if (response.status >= 500)
 | |
|       return true;
 | |
|     return false;
 | |
|   }
 | |
|   async retryRequest(options, retriesRemaining, responseHeaders) {
 | |
|     let timeoutMillis;
 | |
|     const retryAfterMillisHeader = responseHeaders?.["retry-after-ms"];
 | |
|     if (retryAfterMillisHeader) {
 | |
|       const timeoutMs = parseFloat(retryAfterMillisHeader);
 | |
|       if (!Number.isNaN(timeoutMs)) {
 | |
|         timeoutMillis = timeoutMs;
 | |
|       }
 | |
|     }
 | |
|     const retryAfterHeader = responseHeaders?.["retry-after"];
 | |
|     if (retryAfterHeader && !timeoutMillis) {
 | |
|       const timeoutSeconds = parseFloat(retryAfterHeader);
 | |
|       if (!Number.isNaN(timeoutSeconds)) {
 | |
|         timeoutMillis = timeoutSeconds * 1e3;
 | |
|       } else {
 | |
|         timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
 | |
|       }
 | |
|     }
 | |
|     if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1e3)) {
 | |
|       const maxRetries = options.maxRetries ?? this.maxRetries;
 | |
|       timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
 | |
|     }
 | |
|     await sleep(timeoutMillis);
 | |
|     return this.makeRequest(options, retriesRemaining - 1);
 | |
|   }
 | |
|   calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
 | |
|     const initialRetryDelay = 0.5;
 | |
|     const maxRetryDelay = 8;
 | |
|     const numRetries = maxRetries - retriesRemaining;
 | |
|     const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
 | |
|     const jitter = 1 - Math.random() * 0.25;
 | |
|     return sleepSeconds * jitter * 1e3;
 | |
|   }
 | |
|   getUserAgent() {
 | |
|     return `${this.constructor.name}/JS ${VERSION}`;
 | |
|   }
 | |
| };
 | |
| var AbstractPage = class {
 | |
|   constructor(client, response, body, options) {
 | |
|     _AbstractPage_client.set(this, void 0);
 | |
|     __classPrivateFieldSet2(this, _AbstractPage_client, client, "f");
 | |
|     this.options = options;
 | |
|     this.response = response;
 | |
|     this.body = body;
 | |
|   }
 | |
|   hasNextPage() {
 | |
|     const items = this.getPaginatedItems();
 | |
|     if (!items.length)
 | |
|       return false;
 | |
|     return this.nextPageInfo() != null;
 | |
|   }
 | |
|   async getNextPage() {
 | |
|     const nextInfo = this.nextPageInfo();
 | |
|     if (!nextInfo) {
 | |
|       throw new OpenAIError("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");
 | |
|     }
 | |
|     const nextOptions = { ...this.options };
 | |
|     if ("params" in nextInfo && typeof nextOptions.query === "object") {
 | |
|       nextOptions.query = { ...nextOptions.query, ...nextInfo.params };
 | |
|     } else if ("url" in nextInfo) {
 | |
|       const params = [...Object.entries(nextOptions.query || {}), ...nextInfo.url.searchParams.entries()];
 | |
|       for (const [key, value] of params) {
 | |
|         nextInfo.url.searchParams.set(key, value);
 | |
|       }
 | |
|       nextOptions.query = void 0;
 | |
|       nextOptions.path = nextInfo.url.toString();
 | |
|     }
 | |
|     return await __classPrivateFieldGet2(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions);
 | |
|   }
 | |
|   async *iterPages() {
 | |
|     let page = this;
 | |
|     yield page;
 | |
|     while (page.hasNextPage()) {
 | |
|       page = await page.getNextPage();
 | |
|       yield page;
 | |
|     }
 | |
|   }
 | |
|   async *[(_AbstractPage_client = /* @__PURE__ */ new WeakMap(), Symbol.asyncIterator)]() {
 | |
|     for await (const page of this.iterPages()) {
 | |
|       for (const item of page.getPaginatedItems()) {
 | |
|         yield item;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| };
 | |
| var PagePromise = class extends APIPromise {
 | |
|   constructor(client, request, Page2) {
 | |
|     super(request, async (props) => new Page2(client, props.response, await defaultParseResponse(props), props.options));
 | |
|   }
 | |
|   async *[Symbol.asyncIterator]() {
 | |
|     const page = await this;
 | |
|     for await (const item of page) {
 | |
|       yield item;
 | |
|     }
 | |
|   }
 | |
| };
 | |
| var createResponseHeaders = (headers) => {
 | |
|   return new Proxy(Object.fromEntries(headers.entries()), {
 | |
|     get(target, name) {
 | |
|       const key = name.toString();
 | |
|       return target[key.toLowerCase()] || target[key];
 | |
|     }
 | |
|   });
 | |
| };
 | |
| var requestOptionsKeys = {
 | |
|   method: true,
 | |
|   path: true,
 | |
|   query: true,
 | |
|   body: true,
 | |
|   headers: true,
 | |
|   maxRetries: true,
 | |
|   stream: true,
 | |
|   timeout: true,
 | |
|   httpAgent: true,
 | |
|   signal: true,
 | |
|   idempotencyKey: true,
 | |
|   __binaryRequest: true,
 | |
|   __binaryResponse: true,
 | |
|   __streamClass: true
 | |
| };
 | |
| var isRequestOptions = (obj) => {
 | |
|   return typeof obj === "object" && obj !== null && !isEmptyObj(obj) && Object.keys(obj).every((k) => hasOwn2(requestOptionsKeys, k));
 | |
| };
 | |
| var getPlatformProperties = () => {
 | |
|   if (typeof Deno !== "undefined" && Deno.build != null) {
 | |
|     return {
 | |
|       "X-Stainless-Lang": "js",
 | |
|       "X-Stainless-Package-Version": VERSION,
 | |
|       "X-Stainless-OS": normalizePlatform(Deno.build.os),
 | |
|       "X-Stainless-Arch": normalizeArch(Deno.build.arch),
 | |
|       "X-Stainless-Runtime": "deno",
 | |
|       "X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : Deno.version?.deno ?? "unknown"
 | |
|     };
 | |
|   }
 | |
|   if (typeof EdgeRuntime !== "undefined") {
 | |
|     return {
 | |
|       "X-Stainless-Lang": "js",
 | |
|       "X-Stainless-Package-Version": VERSION,
 | |
|       "X-Stainless-OS": "Unknown",
 | |
|       "X-Stainless-Arch": `other:${EdgeRuntime}`,
 | |
|       "X-Stainless-Runtime": "edge",
 | |
|       "X-Stainless-Runtime-Version": process.version
 | |
|     };
 | |
|   }
 | |
|   if (Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]") {
 | |
|     return {
 | |
|       "X-Stainless-Lang": "js",
 | |
|       "X-Stainless-Package-Version": VERSION,
 | |
|       "X-Stainless-OS": normalizePlatform(process.platform),
 | |
|       "X-Stainless-Arch": normalizeArch(process.arch),
 | |
|       "X-Stainless-Runtime": "node",
 | |
|       "X-Stainless-Runtime-Version": process.version
 | |
|     };
 | |
|   }
 | |
|   const browserInfo = getBrowserInfo();
 | |
|   if (browserInfo) {
 | |
|     return {
 | |
|       "X-Stainless-Lang": "js",
 | |
|       "X-Stainless-Package-Version": VERSION,
 | |
|       "X-Stainless-OS": "Unknown",
 | |
|       "X-Stainless-Arch": "unknown",
 | |
|       "X-Stainless-Runtime": `browser:${browserInfo.browser}`,
 | |
|       "X-Stainless-Runtime-Version": browserInfo.version
 | |
|     };
 | |
|   }
 | |
|   return {
 | |
|     "X-Stainless-Lang": "js",
 | |
|     "X-Stainless-Package-Version": VERSION,
 | |
|     "X-Stainless-OS": "Unknown",
 | |
|     "X-Stainless-Arch": "unknown",
 | |
|     "X-Stainless-Runtime": "unknown",
 | |
|     "X-Stainless-Runtime-Version": "unknown"
 | |
|   };
 | |
| };
 | |
| function getBrowserInfo() {
 | |
|   if (typeof navigator === "undefined" || !navigator) {
 | |
|     return null;
 | |
|   }
 | |
|   const browserPatterns = [
 | |
|     { key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
 | |
|     { key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
 | |
|     { key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
 | |
|     { key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
 | |
|     { key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
 | |
|     { key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }
 | |
|   ];
 | |
|   for (const { key, pattern } of browserPatterns) {
 | |
|     const match = pattern.exec(navigator.userAgent);
 | |
|     if (match) {
 | |
|       const major = match[1] || 0;
 | |
|       const minor = match[2] || 0;
 | |
|       const patch = match[3] || 0;
 | |
|       return { browser: key, version: `${major}.${minor}.${patch}` };
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| }
 | |
| var normalizeArch = (arch) => {
 | |
|   if (arch === "x32")
 | |
|     return "x32";
 | |
|   if (arch === "x86_64" || arch === "x64")
 | |
|     return "x64";
 | |
|   if (arch === "arm")
 | |
|     return "arm";
 | |
|   if (arch === "aarch64" || arch === "arm64")
 | |
|     return "arm64";
 | |
|   if (arch)
 | |
|     return `other:${arch}`;
 | |
|   return "unknown";
 | |
| };
 | |
| var normalizePlatform = (platform) => {
 | |
|   platform = platform.toLowerCase();
 | |
|   if (platform.includes("ios"))
 | |
|     return "iOS";
 | |
|   if (platform === "android")
 | |
|     return "Android";
 | |
|   if (platform === "darwin")
 | |
|     return "MacOS";
 | |
|   if (platform === "win32")
 | |
|     return "Windows";
 | |
|   if (platform === "freebsd")
 | |
|     return "FreeBSD";
 | |
|   if (platform === "openbsd")
 | |
|     return "OpenBSD";
 | |
|   if (platform === "linux")
 | |
|     return "Linux";
 | |
|   if (platform)
 | |
|     return `Other:${platform}`;
 | |
|   return "Unknown";
 | |
| };
 | |
| var _platformHeaders;
 | |
| var getPlatformHeaders = () => {
 | |
|   return _platformHeaders ?? (_platformHeaders = getPlatformProperties());
 | |
| };
 | |
| var safeJSON = (text2) => {
 | |
|   try {
 | |
|     return JSON.parse(text2);
 | |
|   } catch (err) {
 | |
|     return void 0;
 | |
|   }
 | |
| };
 | |
| var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
 | |
| var isAbsoluteURL = (url) => {
 | |
|   return startsWithSchemeRegexp.test(url);
 | |
| };
 | |
| var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
 | |
| var validatePositiveInteger = (name, n) => {
 | |
|   if (typeof n !== "number" || !Number.isInteger(n)) {
 | |
|     throw new OpenAIError(`${name} must be an integer`);
 | |
|   }
 | |
|   if (n < 0) {
 | |
|     throw new OpenAIError(`${name} must be a positive integer`);
 | |
|   }
 | |
|   return n;
 | |
| };
 | |
| var castToError = (err) => {
 | |
|   if (err instanceof Error)
 | |
|     return err;
 | |
|   return new Error(err);
 | |
| };
 | |
| var readEnv = (env) => {
 | |
|   if (typeof process !== "undefined") {
 | |
|     return process.env?.[env]?.trim() ?? void 0;
 | |
|   }
 | |
|   if (typeof Deno !== "undefined") {
 | |
|     return Deno.env?.get?.(env)?.trim();
 | |
|   }
 | |
|   return void 0;
 | |
| };
 | |
| function isEmptyObj(obj) {
 | |
|   if (!obj)
 | |
|     return true;
 | |
|   for (const _k in obj)
 | |
|     return false;
 | |
|   return true;
 | |
| }
 | |
| function hasOwn2(obj, key) {
 | |
|   return Object.prototype.hasOwnProperty.call(obj, key);
 | |
| }
 | |
| function applyHeadersMut(targetHeaders, newHeaders) {
 | |
|   for (const k in newHeaders) {
 | |
|     if (!hasOwn2(newHeaders, k))
 | |
|       continue;
 | |
|     const lowerKey = k.toLowerCase();
 | |
|     if (!lowerKey)
 | |
|       continue;
 | |
|     const val = newHeaders[k];
 | |
|     if (val === null) {
 | |
|       delete targetHeaders[lowerKey];
 | |
|     } else if (val !== void 0) {
 | |
|       targetHeaders[lowerKey] = val;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| function debug(action, ...args) {
 | |
|   if (typeof process !== "undefined" && process?.env?.["DEBUG"] === "true") {
 | |
|     console.log(`OpenAI:DEBUG:${action}`, ...args);
 | |
|   }
 | |
| }
 | |
| var uuid4 = () => {
 | |
|   return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
 | |
|     const r = Math.random() * 16 | 0;
 | |
|     const v = c === "x" ? r : r & 3 | 8;
 | |
|     return v.toString(16);
 | |
|   });
 | |
| };
 | |
| var isRunningInBrowser = () => {
 | |
|   return typeof window !== "undefined" && typeof window.document !== "undefined" && typeof navigator !== "undefined";
 | |
| };
 | |
| function isObj(obj) {
 | |
|   return obj != null && typeof obj === "object" && !Array.isArray(obj);
 | |
| }
 | |
| 
 | |
| // node_modules/openai/error.mjs
 | |
| var OpenAIError = class extends Error {
 | |
| };
 | |
| var APIError = class extends OpenAIError {
 | |
|   constructor(status, error, message, headers) {
 | |
|     super(`${APIError.makeMessage(status, error, message)}`);
 | |
|     this.status = status;
 | |
|     this.headers = headers;
 | |
|     this.request_id = headers?.["x-request-id"];
 | |
|     const data = error;
 | |
|     this.error = data;
 | |
|     this.code = data?.["code"];
 | |
|     this.param = data?.["param"];
 | |
|     this.type = data?.["type"];
 | |
|   }
 | |
|   static makeMessage(status, error, message) {
 | |
|     const msg = error?.message ? typeof error.message === "string" ? error.message : JSON.stringify(error.message) : error ? JSON.stringify(error) : message;
 | |
|     if (status && msg) {
 | |
|       return `${status} ${msg}`;
 | |
|     }
 | |
|     if (status) {
 | |
|       return `${status} status code (no body)`;
 | |
|     }
 | |
|     if (msg) {
 | |
|       return msg;
 | |
|     }
 | |
|     return "(no status code or body)";
 | |
|   }
 | |
|   static generate(status, errorResponse, message, headers) {
 | |
|     if (!status) {
 | |
|       return new APIConnectionError({ cause: castToError(errorResponse) });
 | |
|     }
 | |
|     const error = errorResponse?.["error"];
 | |
|     if (status === 400) {
 | |
|       return new BadRequestError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 401) {
 | |
|       return new AuthenticationError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 403) {
 | |
|       return new PermissionDeniedError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 404) {
 | |
|       return new NotFoundError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 409) {
 | |
|       return new ConflictError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 422) {
 | |
|       return new UnprocessableEntityError(status, error, message, headers);
 | |
|     }
 | |
|     if (status === 429) {
 | |
|       return new RateLimitError(status, error, message, headers);
 | |
|     }
 | |
|     if (status >= 500) {
 | |
|       return new InternalServerError(status, error, message, headers);
 | |
|     }
 | |
|     return new APIError(status, error, message, headers);
 | |
|   }
 | |
| };
 | |
| var APIUserAbortError = class extends APIError {
 | |
|   constructor({ message } = {}) {
 | |
|     super(void 0, void 0, message || "Request was aborted.", void 0);
 | |
|     this.status = void 0;
 | |
|   }
 | |
| };
 | |
| var APIConnectionError = class extends APIError {
 | |
|   constructor({ message, cause }) {
 | |
|     super(void 0, void 0, message || "Connection error.", void 0);
 | |
|     this.status = void 0;
 | |
|     if (cause)
 | |
|       this.cause = cause;
 | |
|   }
 | |
| };
 | |
| var APIConnectionTimeoutError = class extends APIConnectionError {
 | |
|   constructor({ message } = {}) {
 | |
|     super({ message: message ?? "Request timed out." });
 | |
|   }
 | |
| };
 | |
| var BadRequestError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 400;
 | |
|   }
 | |
| };
 | |
| var AuthenticationError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 401;
 | |
|   }
 | |
| };
 | |
| var PermissionDeniedError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 403;
 | |
|   }
 | |
| };
 | |
| var NotFoundError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 404;
 | |
|   }
 | |
| };
 | |
| var ConflictError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 409;
 | |
|   }
 | |
| };
 | |
| var UnprocessableEntityError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 422;
 | |
|   }
 | |
| };
 | |
| var RateLimitError = class extends APIError {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.status = 429;
 | |
|   }
 | |
| };
 | |
| var InternalServerError = class extends APIError {
 | |
| };
 | |
| 
 | |
| // node_modules/openai/pagination.mjs
 | |
| var Page = class extends AbstractPage {
 | |
|   constructor(client, response, body, options) {
 | |
|     super(client, response, body, options);
 | |
|     this.data = body.data || [];
 | |
|     this.object = body.object;
 | |
|   }
 | |
|   getPaginatedItems() {
 | |
|     return this.data ?? [];
 | |
|   }
 | |
|   nextPageParams() {
 | |
|     return null;
 | |
|   }
 | |
|   nextPageInfo() {
 | |
|     return null;
 | |
|   }
 | |
| };
 | |
| var CursorPage = class extends AbstractPage {
 | |
|   constructor(client, response, body, options) {
 | |
|     super(client, response, body, options);
 | |
|     this.data = body.data || [];
 | |
|   }
 | |
|   getPaginatedItems() {
 | |
|     return this.data ?? [];
 | |
|   }
 | |
|   nextPageParams() {
 | |
|     const info = this.nextPageInfo();
 | |
|     if (!info)
 | |
|       return null;
 | |
|     if ("params" in info)
 | |
|       return info.params;
 | |
|     const params = Object.fromEntries(info.url.searchParams);
 | |
|     if (!Object.keys(params).length)
 | |
|       return null;
 | |
|     return params;
 | |
|   }
 | |
|   nextPageInfo() {
 | |
|     const data = this.getPaginatedItems();
 | |
|     if (!data.length) {
 | |
|       return null;
 | |
|     }
 | |
|     const id = data[data.length - 1]?.id;
 | |
|     if (!id) {
 | |
|       return null;
 | |
|     }
 | |
|     return { params: { after: id } };
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resource.mjs
 | |
| var APIResource = class {
 | |
|   constructor(client) {
 | |
|     this._client = client;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resources/chat/completions.mjs
 | |
| var Completions = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/chat/completions", { body, ...options, stream: body.stream ?? false });
 | |
|   }
 | |
| };
 | |
| (function(Completions4) {
 | |
| })(Completions || (Completions = {}));
 | |
| 
 | |
| // node_modules/openai/resources/chat/chat.mjs
 | |
| var Chat = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.completions = new Completions(this._client);
 | |
|   }
 | |
| };
 | |
| (function(Chat3) {
 | |
|   Chat3.Completions = Completions;
 | |
| })(Chat || (Chat = {}));
 | |
| 
 | |
| // node_modules/openai/resources/audio/speech.mjs
 | |
| var Speech = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/audio/speech", { body, ...options, __binaryResponse: true });
 | |
|   }
 | |
| };
 | |
| (function(Speech2) {
 | |
| })(Speech || (Speech = {}));
 | |
| 
 | |
| // node_modules/openai/resources/audio/transcriptions.mjs
 | |
| var Transcriptions = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/audio/transcriptions", multipartFormRequestOptions({ body, ...options }));
 | |
|   }
 | |
| };
 | |
| (function(Transcriptions2) {
 | |
| })(Transcriptions || (Transcriptions = {}));
 | |
| 
 | |
| // node_modules/openai/resources/audio/translations.mjs
 | |
| var Translations = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/audio/translations", multipartFormRequestOptions({ body, ...options }));
 | |
|   }
 | |
| };
 | |
| (function(Translations2) {
 | |
| })(Translations || (Translations = {}));
 | |
| 
 | |
| // node_modules/openai/resources/audio/audio.mjs
 | |
| var Audio = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.transcriptions = new Transcriptions(this._client);
 | |
|     this.translations = new Translations(this._client);
 | |
|     this.speech = new Speech(this._client);
 | |
|   }
 | |
| };
 | |
| (function(Audio2) {
 | |
|   Audio2.Transcriptions = Transcriptions;
 | |
|   Audio2.Translations = Translations;
 | |
|   Audio2.Speech = Speech;
 | |
| })(Audio || (Audio = {}));
 | |
| 
 | |
| // node_modules/openai/resources/batches.mjs
 | |
| var Batches = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/batches", { body, ...options });
 | |
|   }
 | |
|   retrieve(batchId, options) {
 | |
|     return this._client.get(`/batches/${batchId}`, options);
 | |
|   }
 | |
|   list(query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list({}, query);
 | |
|     }
 | |
|     return this._client.getAPIList("/batches", BatchesPage, { query, ...options });
 | |
|   }
 | |
|   cancel(batchId, options) {
 | |
|     return this._client.post(`/batches/${batchId}/cancel`, options);
 | |
|   }
 | |
| };
 | |
| var BatchesPage = class extends CursorPage {
 | |
| };
 | |
| (function(Batches2) {
 | |
|   Batches2.BatchesPage = BatchesPage;
 | |
| })(Batches || (Batches = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/assistants.mjs
 | |
| var Assistants = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/assistants", {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(assistantId, options) {
 | |
|     return this._client.get(`/assistants/${assistantId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   update(assistantId, body, options) {
 | |
|     return this._client.post(`/assistants/${assistantId}`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list({}, query);
 | |
|     }
 | |
|     return this._client.getAPIList("/assistants", AssistantsPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   del(assistantId, options) {
 | |
|     return this._client.delete(`/assistants/${assistantId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var AssistantsPage = class extends CursorPage {
 | |
| };
 | |
| (function(Assistants2) {
 | |
|   Assistants2.AssistantsPage = AssistantsPage;
 | |
| })(Assistants || (Assistants = {}));
 | |
| 
 | |
| // node_modules/openai/lib/RunnableFunction.mjs
 | |
| function isRunnableFunctionWithParse(fn) {
 | |
|   return typeof fn.parse === "function";
 | |
| }
 | |
| 
 | |
| // node_modules/openai/lib/chatCompletionUtils.mjs
 | |
| var isAssistantMessage = (message) => {
 | |
|   return message?.role === "assistant";
 | |
| };
 | |
| var isFunctionMessage = (message) => {
 | |
|   return message?.role === "function";
 | |
| };
 | |
| var isToolMessage = (message) => {
 | |
|   return message?.role === "tool";
 | |
| };
 | |
| 
 | |
| // node_modules/openai/lib/AbstractChatCompletionRunner.mjs
 | |
| var __classPrivateFieldSet3 = function(receiver, state, value, kind2, f) {
 | |
|   if (kind2 === "m")
 | |
|     throw new TypeError("Private method is not writable");
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a setter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|   return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
| };
 | |
| var __classPrivateFieldGet3 = function(receiver, state, kind2, f) {
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a getter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|   return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
| };
 | |
| var _AbstractChatCompletionRunner_instances;
 | |
| var _AbstractChatCompletionRunner_connectedPromise;
 | |
| var _AbstractChatCompletionRunner_resolveConnectedPromise;
 | |
| var _AbstractChatCompletionRunner_rejectConnectedPromise;
 | |
| var _AbstractChatCompletionRunner_endPromise;
 | |
| var _AbstractChatCompletionRunner_resolveEndPromise;
 | |
| var _AbstractChatCompletionRunner_rejectEndPromise;
 | |
| var _AbstractChatCompletionRunner_listeners;
 | |
| var _AbstractChatCompletionRunner_ended;
 | |
| var _AbstractChatCompletionRunner_errored;
 | |
| var _AbstractChatCompletionRunner_aborted;
 | |
| var _AbstractChatCompletionRunner_catchingPromiseCreated;
 | |
| var _AbstractChatCompletionRunner_getFinalContent;
 | |
| var _AbstractChatCompletionRunner_getFinalMessage;
 | |
| var _AbstractChatCompletionRunner_getFinalFunctionCall;
 | |
| var _AbstractChatCompletionRunner_getFinalFunctionCallResult;
 | |
| var _AbstractChatCompletionRunner_calculateTotalUsage;
 | |
| var _AbstractChatCompletionRunner_handleError;
 | |
| var _AbstractChatCompletionRunner_validateParams;
 | |
| var _AbstractChatCompletionRunner_stringifyFunctionCallResult;
 | |
| var DEFAULT_MAX_CHAT_COMPLETIONS = 10;
 | |
| var AbstractChatCompletionRunner = class {
 | |
|   constructor() {
 | |
|     _AbstractChatCompletionRunner_instances.add(this);
 | |
|     this.controller = new AbortController();
 | |
|     _AbstractChatCompletionRunner_connectedPromise.set(this, void 0);
 | |
|     _AbstractChatCompletionRunner_resolveConnectedPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractChatCompletionRunner_rejectConnectedPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractChatCompletionRunner_endPromise.set(this, void 0);
 | |
|     _AbstractChatCompletionRunner_resolveEndPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractChatCompletionRunner_rejectEndPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractChatCompletionRunner_listeners.set(this, {});
 | |
|     this._chatCompletions = [];
 | |
|     this.messages = [];
 | |
|     _AbstractChatCompletionRunner_ended.set(this, false);
 | |
|     _AbstractChatCompletionRunner_errored.set(this, false);
 | |
|     _AbstractChatCompletionRunner_aborted.set(this, false);
 | |
|     _AbstractChatCompletionRunner_catchingPromiseCreated.set(this, false);
 | |
|     _AbstractChatCompletionRunner_handleError.set(this, (error) => {
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_errored, true, "f");
 | |
|       if (error instanceof Error && error.name === "AbortError") {
 | |
|         error = new APIUserAbortError();
 | |
|       }
 | |
|       if (error instanceof APIUserAbortError) {
 | |
|         __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_aborted, true, "f");
 | |
|         return this._emit("abort", error);
 | |
|       }
 | |
|       if (error instanceof OpenAIError) {
 | |
|         return this._emit("error", error);
 | |
|       }
 | |
|       if (error instanceof Error) {
 | |
|         const openAIError = new OpenAIError(error.message);
 | |
|         openAIError.cause = error;
 | |
|         return this._emit("error", openAIError);
 | |
|       }
 | |
|       return this._emit("error", new OpenAIError(String(error)));
 | |
|     });
 | |
|     __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_connectedPromise, new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_resolveConnectedPromise, resolve, "f");
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, reject, "f");
 | |
|     }), "f");
 | |
|     __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_endPromise, new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_resolveEndPromise, resolve, "f");
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_rejectEndPromise, reject, "f");
 | |
|     }), "f");
 | |
|     __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_connectedPromise, "f").catch(() => {
 | |
|     });
 | |
|     __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_endPromise, "f").catch(() => {
 | |
|     });
 | |
|   }
 | |
|   _run(executor) {
 | |
|     setTimeout(() => {
 | |
|       executor().then(() => {
 | |
|         this._emitFinal();
 | |
|         this._emit("end");
 | |
|       }, __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_handleError, "f"));
 | |
|     }, 0);
 | |
|   }
 | |
|   _addChatCompletion(chatCompletion) {
 | |
|     this._chatCompletions.push(chatCompletion);
 | |
|     this._emit("chatCompletion", chatCompletion);
 | |
|     const message = chatCompletion.choices[0]?.message;
 | |
|     if (message)
 | |
|       this._addMessage(message);
 | |
|     return chatCompletion;
 | |
|   }
 | |
|   _addMessage(message, emit = true) {
 | |
|     if (!("content" in message))
 | |
|       message.content = null;
 | |
|     this.messages.push(message);
 | |
|     if (emit) {
 | |
|       this._emit("message", message);
 | |
|       if ((isFunctionMessage(message) || isToolMessage(message)) && message.content) {
 | |
|         this._emit("functionCallResult", message.content);
 | |
|       } else if (isAssistantMessage(message) && message.function_call) {
 | |
|         this._emit("functionCall", message.function_call);
 | |
|       } else if (isAssistantMessage(message) && message.tool_calls) {
 | |
|         for (const tool_call of message.tool_calls) {
 | |
|           if (tool_call.type === "function") {
 | |
|             this._emit("functionCall", tool_call.function);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   _connected() {
 | |
|     if (this.ended)
 | |
|       return;
 | |
|     __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_resolveConnectedPromise, "f").call(this);
 | |
|     this._emit("connect");
 | |
|   }
 | |
|   get ended() {
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_ended, "f");
 | |
|   }
 | |
|   get errored() {
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_errored, "f");
 | |
|   }
 | |
|   get aborted() {
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_aborted, "f");
 | |
|   }
 | |
|   abort() {
 | |
|     this.controller.abort();
 | |
|   }
 | |
|   on(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] || (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = []);
 | |
|     listeners.push({ listener });
 | |
|     return this;
 | |
|   }
 | |
|   off(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event];
 | |
|     if (!listeners)
 | |
|       return this;
 | |
|     const index = listeners.findIndex((l) => l.listener === listener);
 | |
|     if (index >= 0)
 | |
|       listeners.splice(index, 1);
 | |
|     return this;
 | |
|   }
 | |
|   once(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] || (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = []);
 | |
|     listeners.push({ listener, once: true });
 | |
|     return this;
 | |
|   }
 | |
|   emitted(event) {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, true, "f");
 | |
|       if (event !== "error")
 | |
|         this.once("error", reject);
 | |
|       this.once(event, resolve);
 | |
|     });
 | |
|   }
 | |
|   async done() {
 | |
|     __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, true, "f");
 | |
|     await __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_endPromise, "f");
 | |
|   }
 | |
|   async finalChatCompletion() {
 | |
|     await this.done();
 | |
|     const completion = this._chatCompletions[this._chatCompletions.length - 1];
 | |
|     if (!completion)
 | |
|       throw new OpenAIError("stream ended without producing a ChatCompletion");
 | |
|     return completion;
 | |
|   }
 | |
|   async finalContent() {
 | |
|     await this.done();
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this);
 | |
|   }
 | |
|   async finalMessage() {
 | |
|     await this.done();
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this);
 | |
|   }
 | |
|   async finalFunctionCall() {
 | |
|     await this.done();
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this);
 | |
|   }
 | |
|   async finalFunctionCallResult() {
 | |
|     await this.done();
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this);
 | |
|   }
 | |
|   async totalUsage() {
 | |
|     await this.done();
 | |
|     return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this);
 | |
|   }
 | |
|   allChatCompletions() {
 | |
|     return [...this._chatCompletions];
 | |
|   }
 | |
|   _emit(event, ...args) {
 | |
|     if (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_ended, "f")) {
 | |
|       return;
 | |
|     }
 | |
|     if (event === "end") {
 | |
|       __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_ended, true, "f");
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_resolveEndPromise, "f").call(this);
 | |
|     }
 | |
|     const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event];
 | |
|     if (listeners) {
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = listeners.filter((l) => !l.once);
 | |
|       listeners.forEach(({ listener }) => listener(...args));
 | |
|     }
 | |
|     if (event === "abort") {
 | |
|       const error = args[0];
 | |
|       if (!__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, "f") && !listeners?.length) {
 | |
|         Promise.reject(error);
 | |
|       }
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, "f").call(this, error);
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectEndPromise, "f").call(this, error);
 | |
|       this._emit("end");
 | |
|       return;
 | |
|     }
 | |
|     if (event === "error") {
 | |
|       const error = args[0];
 | |
|       if (!__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, "f") && !listeners?.length) {
 | |
|         Promise.reject(error);
 | |
|       }
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, "f").call(this, error);
 | |
|       __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectEndPromise, "f").call(this, error);
 | |
|       this._emit("end");
 | |
|     }
 | |
|   }
 | |
|   _emitFinal() {
 | |
|     const completion = this._chatCompletions[this._chatCompletions.length - 1];
 | |
|     if (completion)
 | |
|       this._emit("finalChatCompletion", completion);
 | |
|     const finalMessage = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this);
 | |
|     if (finalMessage)
 | |
|       this._emit("finalMessage", finalMessage);
 | |
|     const finalContent = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this);
 | |
|     if (finalContent)
 | |
|       this._emit("finalContent", finalContent);
 | |
|     const finalFunctionCall = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this);
 | |
|     if (finalFunctionCall)
 | |
|       this._emit("finalFunctionCall", finalFunctionCall);
 | |
|     const finalFunctionCallResult = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this);
 | |
|     if (finalFunctionCallResult != null)
 | |
|       this._emit("finalFunctionCallResult", finalFunctionCallResult);
 | |
|     if (this._chatCompletions.some((c) => c.usage)) {
 | |
|       this._emit("totalUsage", __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this));
 | |
|     }
 | |
|   }
 | |
|   async _createChatCompletion(completions, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_validateParams).call(this, params);
 | |
|     const chatCompletion = await completions.create({ ...params, stream: false }, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     return this._addChatCompletion(chatCompletion);
 | |
|   }
 | |
|   async _runChatCompletion(completions, params, options) {
 | |
|     for (const message of params.messages) {
 | |
|       this._addMessage(message, false);
 | |
|     }
 | |
|     return await this._createChatCompletion(completions, params, options);
 | |
|   }
 | |
|   async _runFunctions(completions, params, options) {
 | |
|     const role = "function";
 | |
|     const { function_call = "auto", stream, ...restParams } = params;
 | |
|     const singleFunctionToCall = typeof function_call !== "string" && function_call?.name;
 | |
|     const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {};
 | |
|     const functionsByName = {};
 | |
|     for (const f of params.functions) {
 | |
|       functionsByName[f.name || f.function.name] = f;
 | |
|     }
 | |
|     const functions = params.functions.map((f) => ({
 | |
|       name: f.name || f.function.name,
 | |
|       parameters: f.parameters,
 | |
|       description: f.description
 | |
|     }));
 | |
|     for (const message of params.messages) {
 | |
|       this._addMessage(message, false);
 | |
|     }
 | |
|     for (let i = 0; i < maxChatCompletions; ++i) {
 | |
|       const chatCompletion = await this._createChatCompletion(completions, {
 | |
|         ...restParams,
 | |
|         function_call,
 | |
|         functions,
 | |
|         messages: [...this.messages]
 | |
|       }, options);
 | |
|       const message = chatCompletion.choices[0]?.message;
 | |
|       if (!message) {
 | |
|         throw new OpenAIError(`missing message in ChatCompletion response`);
 | |
|       }
 | |
|       if (!message.function_call)
 | |
|         return;
 | |
|       const { name, arguments: args } = message.function_call;
 | |
|       const fn = functionsByName[name];
 | |
|       if (!fn) {
 | |
|         const content2 = `Invalid function_call: ${JSON.stringify(name)}. Available options are: ${functions.map((f) => JSON.stringify(f.name)).join(", ")}. Please try again`;
 | |
|         this._addMessage({ role, name, content: content2 });
 | |
|         continue;
 | |
|       } else if (singleFunctionToCall && singleFunctionToCall !== name) {
 | |
|         const content2 = `Invalid function_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`;
 | |
|         this._addMessage({ role, name, content: content2 });
 | |
|         continue;
 | |
|       }
 | |
|       let parsed;
 | |
|       try {
 | |
|         parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args;
 | |
|       } catch (error) {
 | |
|         this._addMessage({
 | |
|           role,
 | |
|           name,
 | |
|           content: error instanceof Error ? error.message : String(error)
 | |
|         });
 | |
|         continue;
 | |
|       }
 | |
|       const rawContent = await fn.function(parsed, this);
 | |
|       const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent);
 | |
|       this._addMessage({ role, name, content });
 | |
|       if (singleFunctionToCall)
 | |
|         return;
 | |
|     }
 | |
|   }
 | |
|   async _runTools(completions, params, options) {
 | |
|     const role = "tool";
 | |
|     const { tool_choice = "auto", stream, ...restParams } = params;
 | |
|     const singleFunctionToCall = typeof tool_choice !== "string" && tool_choice?.function?.name;
 | |
|     const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {};
 | |
|     const functionsByName = {};
 | |
|     for (const f of params.tools) {
 | |
|       if (f.type === "function") {
 | |
|         functionsByName[f.function.name || f.function.function.name] = f.function;
 | |
|       }
 | |
|     }
 | |
|     const tools = "tools" in params ? params.tools.map((t) => t.type === "function" ? {
 | |
|       type: "function",
 | |
|       function: {
 | |
|         name: t.function.name || t.function.function.name,
 | |
|         parameters: t.function.parameters,
 | |
|         description: t.function.description
 | |
|       }
 | |
|     } : t) : void 0;
 | |
|     for (const message of params.messages) {
 | |
|       this._addMessage(message, false);
 | |
|     }
 | |
|     for (let i = 0; i < maxChatCompletions; ++i) {
 | |
|       const chatCompletion = await this._createChatCompletion(completions, {
 | |
|         ...restParams,
 | |
|         tool_choice,
 | |
|         tools,
 | |
|         messages: [...this.messages]
 | |
|       }, options);
 | |
|       const message = chatCompletion.choices[0]?.message;
 | |
|       if (!message) {
 | |
|         throw new OpenAIError(`missing message in ChatCompletion response`);
 | |
|       }
 | |
|       if (!message.tool_calls) {
 | |
|         return;
 | |
|       }
 | |
|       for (const tool_call of message.tool_calls) {
 | |
|         if (tool_call.type !== "function")
 | |
|           continue;
 | |
|         const tool_call_id = tool_call.id;
 | |
|         const { name, arguments: args } = tool_call.function;
 | |
|         const fn = functionsByName[name];
 | |
|         if (!fn) {
 | |
|           const content2 = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${tools.map((f) => JSON.stringify(f.function.name)).join(", ")}. Please try again`;
 | |
|           this._addMessage({ role, tool_call_id, content: content2 });
 | |
|           continue;
 | |
|         } else if (singleFunctionToCall && singleFunctionToCall !== name) {
 | |
|           const content2 = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`;
 | |
|           this._addMessage({ role, tool_call_id, content: content2 });
 | |
|           continue;
 | |
|         }
 | |
|         let parsed;
 | |
|         try {
 | |
|           parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args;
 | |
|         } catch (error) {
 | |
|           const content2 = error instanceof Error ? error.message : String(error);
 | |
|           this._addMessage({ role, tool_call_id, content: content2 });
 | |
|           continue;
 | |
|         }
 | |
|         const rawContent = await fn.function(parsed, this);
 | |
|         const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent);
 | |
|         this._addMessage({ role, tool_call_id, content });
 | |
|         if (singleFunctionToCall) {
 | |
|           return;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
| };
 | |
| _AbstractChatCompletionRunner_connectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_resolveConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_rejectConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_endPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_resolveEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_rejectEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_listeners = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_ended = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_errored = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_aborted = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_catchingPromiseCreated = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_handleError = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_instances = /* @__PURE__ */ new WeakSet(), _AbstractChatCompletionRunner_getFinalContent = function _AbstractChatCompletionRunner_getFinalContent2() {
 | |
|   return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this).content ?? null;
 | |
| }, _AbstractChatCompletionRunner_getFinalMessage = function _AbstractChatCompletionRunner_getFinalMessage2() {
 | |
|   let i = this.messages.length;
 | |
|   while (i-- > 0) {
 | |
|     const message = this.messages[i];
 | |
|     if (isAssistantMessage(message)) {
 | |
|       const { function_call, ...rest } = message;
 | |
|       const ret = { ...rest, content: message.content ?? null };
 | |
|       if (function_call) {
 | |
|         ret.function_call = function_call;
 | |
|       }
 | |
|       return ret;
 | |
|     }
 | |
|   }
 | |
|   throw new OpenAIError("stream ended without producing a ChatCompletionMessage with role=assistant");
 | |
| }, _AbstractChatCompletionRunner_getFinalFunctionCall = function _AbstractChatCompletionRunner_getFinalFunctionCall2() {
 | |
|   for (let i = this.messages.length - 1; i >= 0; i--) {
 | |
|     const message = this.messages[i];
 | |
|     if (isAssistantMessage(message) && message?.function_call) {
 | |
|       return message.function_call;
 | |
|     }
 | |
|     if (isAssistantMessage(message) && message?.tool_calls?.length) {
 | |
|       return message.tool_calls.at(-1)?.function;
 | |
|     }
 | |
|   }
 | |
|   return;
 | |
| }, _AbstractChatCompletionRunner_getFinalFunctionCallResult = function _AbstractChatCompletionRunner_getFinalFunctionCallResult2() {
 | |
|   for (let i = this.messages.length - 1; i >= 0; i--) {
 | |
|     const message = this.messages[i];
 | |
|     if (isFunctionMessage(message) && message.content != null) {
 | |
|       return message.content;
 | |
|     }
 | |
|     if (isToolMessage(message) && message.content != null && this.messages.some((x) => x.role === "assistant" && x.tool_calls?.some((y) => y.type === "function" && y.id === message.tool_call_id))) {
 | |
|       return message.content;
 | |
|     }
 | |
|   }
 | |
|   return;
 | |
| }, _AbstractChatCompletionRunner_calculateTotalUsage = function _AbstractChatCompletionRunner_calculateTotalUsage2() {
 | |
|   const total = {
 | |
|     completion_tokens: 0,
 | |
|     prompt_tokens: 0,
 | |
|     total_tokens: 0
 | |
|   };
 | |
|   for (const { usage } of this._chatCompletions) {
 | |
|     if (usage) {
 | |
|       total.completion_tokens += usage.completion_tokens;
 | |
|       total.prompt_tokens += usage.prompt_tokens;
 | |
|       total.total_tokens += usage.total_tokens;
 | |
|     }
 | |
|   }
 | |
|   return total;
 | |
| }, _AbstractChatCompletionRunner_validateParams = function _AbstractChatCompletionRunner_validateParams2(params) {
 | |
|   if (params.n != null && params.n > 1) {
 | |
|     throw new OpenAIError("ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly.");
 | |
|   }
 | |
| }, _AbstractChatCompletionRunner_stringifyFunctionCallResult = function _AbstractChatCompletionRunner_stringifyFunctionCallResult2(rawContent) {
 | |
|   return typeof rawContent === "string" ? rawContent : rawContent === void 0 ? "undefined" : JSON.stringify(rawContent);
 | |
| };
 | |
| 
 | |
| // node_modules/openai/lib/ChatCompletionRunner.mjs
 | |
| var ChatCompletionRunner = class extends AbstractChatCompletionRunner {
 | |
|   static runFunctions(completions, params, options) {
 | |
|     const runner = new ChatCompletionRunner();
 | |
|     const opts = {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "runFunctions" }
 | |
|     };
 | |
|     runner._run(() => runner._runFunctions(completions, params, opts));
 | |
|     return runner;
 | |
|   }
 | |
|   static runTools(completions, params, options) {
 | |
|     const runner = new ChatCompletionRunner();
 | |
|     const opts = {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "runTools" }
 | |
|     };
 | |
|     runner._run(() => runner._runTools(completions, params, opts));
 | |
|     return runner;
 | |
|   }
 | |
|   _addMessage(message) {
 | |
|     super._addMessage(message);
 | |
|     if (isAssistantMessage(message) && message.content) {
 | |
|       this._emit("content", message.content);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/lib/ChatCompletionStream.mjs
 | |
| var __classPrivateFieldGet4 = function(receiver, state, kind2, f) {
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a getter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|   return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
| };
 | |
| var __classPrivateFieldSet4 = function(receiver, state, value, kind2, f) {
 | |
|   if (kind2 === "m")
 | |
|     throw new TypeError("Private method is not writable");
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a setter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|   return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
| };
 | |
| var _ChatCompletionStream_instances;
 | |
| var _ChatCompletionStream_currentChatCompletionSnapshot;
 | |
| var _ChatCompletionStream_beginRequest;
 | |
| var _ChatCompletionStream_addChunk;
 | |
| var _ChatCompletionStream_endRequest;
 | |
| var _ChatCompletionStream_accumulateChatCompletion;
 | |
| var ChatCompletionStream = class extends AbstractChatCompletionRunner {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     _ChatCompletionStream_instances.add(this);
 | |
|     _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0);
 | |
|   }
 | |
|   get currentChatCompletionSnapshot() {
 | |
|     return __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|   }
 | |
|   static fromReadableStream(stream) {
 | |
|     const runner = new ChatCompletionStream();
 | |
|     runner._run(() => runner._fromReadableStream(stream));
 | |
|     return runner;
 | |
|   }
 | |
|   static createChatCompletion(completions, params, options) {
 | |
|     const runner = new ChatCompletionStream();
 | |
|     runner._run(() => runner._runChatCompletion(completions, { ...params, stream: true }, { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" } }));
 | |
|     return runner;
 | |
|   }
 | |
|   async _createChatCompletion(completions, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
 | |
|     const stream = await completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     for await (const chunk of stream) {
 | |
|       __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|   }
 | |
|   async _fromReadableStream(readableStream, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
 | |
|     this._connected();
 | |
|     const stream = Stream.fromReadableStream(readableStream, this.controller);
 | |
|     let chatId;
 | |
|     for await (const chunk of stream) {
 | |
|       if (chatId && chatId !== chunk.id) {
 | |
|         this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|       }
 | |
|       __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
 | |
|       chatId = chunk.id;
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|   }
 | |
|   [(_ChatCompletionStream_currentChatCompletionSnapshot = /* @__PURE__ */ new WeakMap(), _ChatCompletionStream_instances = /* @__PURE__ */ new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest2() {
 | |
|     if (this.ended)
 | |
|       return;
 | |
|     __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f");
 | |
|   }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk2(chunk) {
 | |
|     if (this.ended)
 | |
|       return;
 | |
|     const completion = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk);
 | |
|     this._emit("chunk", chunk, completion);
 | |
|     const delta = chunk.choices[0]?.delta?.content;
 | |
|     const snapshot = completion.choices[0]?.message;
 | |
|     if (delta != null && snapshot?.role === "assistant" && snapshot?.content) {
 | |
|       this._emit("content", delta, snapshot.content);
 | |
|     }
 | |
|   }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest2() {
 | |
|     if (this.ended) {
 | |
|       throw new OpenAIError(`stream has ended, this shouldn't happen`);
 | |
|     }
 | |
|     const snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|     if (!snapshot) {
 | |
|       throw new OpenAIError(`request ended without sending any chunks`);
 | |
|     }
 | |
|     __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f");
 | |
|     return finalizeChatCompletion(snapshot);
 | |
|   }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion2(chunk) {
 | |
|     var _a2, _b, _c;
 | |
|     let snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|     const { choices, ...rest } = chunk;
 | |
|     if (!snapshot) {
 | |
|       snapshot = __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, {
 | |
|         ...rest,
 | |
|         choices: []
 | |
|       }, "f");
 | |
|     } else {
 | |
|       Object.assign(snapshot, rest);
 | |
|     }
 | |
|     for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) {
 | |
|       let choice = snapshot.choices[index];
 | |
|       if (!choice) {
 | |
|         choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other };
 | |
|       }
 | |
|       if (logprobs) {
 | |
|         if (!choice.logprobs) {
 | |
|           choice.logprobs = Object.assign({}, logprobs);
 | |
|         } else {
 | |
|           const { content: content2, ...rest3 } = logprobs;
 | |
|           Object.assign(choice.logprobs, rest3);
 | |
|           if (content2) {
 | |
|             (_a2 = choice.logprobs).content ?? (_a2.content = []);
 | |
|             choice.logprobs.content.push(...content2);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if (finish_reason)
 | |
|         choice.finish_reason = finish_reason;
 | |
|       Object.assign(choice, other);
 | |
|       if (!delta)
 | |
|         continue;
 | |
|       const { content, function_call, role, tool_calls, ...rest2 } = delta;
 | |
|       Object.assign(choice.message, rest2);
 | |
|       if (content)
 | |
|         choice.message.content = (choice.message.content || "") + content;
 | |
|       if (role)
 | |
|         choice.message.role = role;
 | |
|       if (function_call) {
 | |
|         if (!choice.message.function_call) {
 | |
|           choice.message.function_call = function_call;
 | |
|         } else {
 | |
|           if (function_call.name)
 | |
|             choice.message.function_call.name = function_call.name;
 | |
|           if (function_call.arguments) {
 | |
|             (_b = choice.message.function_call).arguments ?? (_b.arguments = "");
 | |
|             choice.message.function_call.arguments += function_call.arguments;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if (tool_calls) {
 | |
|         if (!choice.message.tool_calls)
 | |
|           choice.message.tool_calls = [];
 | |
|         for (const { index: index2, id, type, function: fn, ...rest3 } of tool_calls) {
 | |
|           const tool_call = (_c = choice.message.tool_calls)[index2] ?? (_c[index2] = {});
 | |
|           Object.assign(tool_call, rest3);
 | |
|           if (id)
 | |
|             tool_call.id = id;
 | |
|           if (type)
 | |
|             tool_call.type = type;
 | |
|           if (fn)
 | |
|             tool_call.function ?? (tool_call.function = { arguments: "" });
 | |
|           if (fn?.name)
 | |
|             tool_call.function.name = fn.name;
 | |
|           if (fn?.arguments)
 | |
|             tool_call.function.arguments += fn.arguments;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return snapshot;
 | |
|   }, Symbol.asyncIterator)]() {
 | |
|     const pushQueue = [];
 | |
|     const readQueue = [];
 | |
|     let done = false;
 | |
|     this.on("chunk", (chunk) => {
 | |
|       const reader = readQueue.shift();
 | |
|       if (reader) {
 | |
|         reader.resolve(chunk);
 | |
|       } else {
 | |
|         pushQueue.push(chunk);
 | |
|       }
 | |
|     });
 | |
|     this.on("end", () => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.resolve(void 0);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     this.on("abort", (err) => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.reject(err);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     this.on("error", (err) => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.reject(err);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     return {
 | |
|       next: async () => {
 | |
|         if (!pushQueue.length) {
 | |
|           if (done) {
 | |
|             return { value: void 0, done: true };
 | |
|           }
 | |
|           return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
 | |
|         }
 | |
|         const chunk = pushQueue.shift();
 | |
|         return { value: chunk, done: false };
 | |
|       },
 | |
|       return: async () => {
 | |
|         this.abort();
 | |
|         return { value: void 0, done: true };
 | |
|       }
 | |
|     };
 | |
|   }
 | |
|   toReadableStream() {
 | |
|     const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
 | |
|     return stream.toReadableStream();
 | |
|   }
 | |
| };
 | |
| function finalizeChatCompletion(snapshot) {
 | |
|   const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
 | |
|   return {
 | |
|     ...rest,
 | |
|     id,
 | |
|     choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => {
 | |
|       if (!finish_reason)
 | |
|         throw new OpenAIError(`missing finish_reason for choice ${index}`);
 | |
|       const { content = null, function_call, tool_calls, ...messageRest } = message;
 | |
|       const role = message.role;
 | |
|       if (!role)
 | |
|         throw new OpenAIError(`missing role for choice ${index}`);
 | |
|       if (function_call) {
 | |
|         const { arguments: args, name } = function_call;
 | |
|         if (args == null)
 | |
|           throw new OpenAIError(`missing function_call.arguments for choice ${index}`);
 | |
|         if (!name)
 | |
|           throw new OpenAIError(`missing function_call.name for choice ${index}`);
 | |
|         return {
 | |
|           ...choiceRest,
 | |
|           message: { content, function_call: { arguments: args, name }, role },
 | |
|           finish_reason,
 | |
|           index,
 | |
|           logprobs
 | |
|         };
 | |
|       }
 | |
|       if (tool_calls) {
 | |
|         return {
 | |
|           ...choiceRest,
 | |
|           index,
 | |
|           finish_reason,
 | |
|           logprobs,
 | |
|           message: {
 | |
|             ...messageRest,
 | |
|             role,
 | |
|             content,
 | |
|             tool_calls: tool_calls.map((tool_call, i) => {
 | |
|               const { function: fn, type, id: id2, ...toolRest } = tool_call;
 | |
|               const { arguments: args, name, ...fnRest } = fn || {};
 | |
|               if (id2 == null)
 | |
|                 throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id
 | |
| ${str(snapshot)}`);
 | |
|               if (type == null)
 | |
|                 throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type
 | |
| ${str(snapshot)}`);
 | |
|               if (name == null)
 | |
|                 throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name
 | |
| ${str(snapshot)}`);
 | |
|               if (args == null)
 | |
|                 throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments
 | |
| ${str(snapshot)}`);
 | |
|               return { ...toolRest, id: id2, type, function: { ...fnRest, name, arguments: args } };
 | |
|             })
 | |
|           }
 | |
|         };
 | |
|       }
 | |
|       return {
 | |
|         ...choiceRest,
 | |
|         message: { ...messageRest, content, role },
 | |
|         finish_reason,
 | |
|         index,
 | |
|         logprobs
 | |
|       };
 | |
|     }),
 | |
|     created,
 | |
|     model,
 | |
|     object: "chat.completion",
 | |
|     ...system_fingerprint ? { system_fingerprint } : {}
 | |
|   };
 | |
| }
 | |
| function str(x) {
 | |
|   return JSON.stringify(x);
 | |
| }
 | |
| 
 | |
| // node_modules/openai/lib/ChatCompletionStreamingRunner.mjs
 | |
| var ChatCompletionStreamingRunner = class extends ChatCompletionStream {
 | |
|   static fromReadableStream(stream) {
 | |
|     const runner = new ChatCompletionStreamingRunner();
 | |
|     runner._run(() => runner._fromReadableStream(stream));
 | |
|     return runner;
 | |
|   }
 | |
|   static runFunctions(completions, params, options) {
 | |
|     const runner = new ChatCompletionStreamingRunner();
 | |
|     const opts = {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "runFunctions" }
 | |
|     };
 | |
|     runner._run(() => runner._runFunctions(completions, params, opts));
 | |
|     return runner;
 | |
|   }
 | |
|   static runTools(completions, params, options) {
 | |
|     const runner = new ChatCompletionStreamingRunner();
 | |
|     const opts = {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "runTools" }
 | |
|     };
 | |
|     runner._run(() => runner._runTools(completions, params, opts));
 | |
|     return runner;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resources/beta/chat/completions.mjs
 | |
| var Completions2 = class extends APIResource {
 | |
|   runFunctions(body, options) {
 | |
|     if (body.stream) {
 | |
|       return ChatCompletionStreamingRunner.runFunctions(this._client.chat.completions, body, options);
 | |
|     }
 | |
|     return ChatCompletionRunner.runFunctions(this._client.chat.completions, body, options);
 | |
|   }
 | |
|   runTools(body, options) {
 | |
|     if (body.stream) {
 | |
|       return ChatCompletionStreamingRunner.runTools(this._client.chat.completions, body, options);
 | |
|     }
 | |
|     return ChatCompletionRunner.runTools(this._client.chat.completions, body, options);
 | |
|   }
 | |
|   stream(body, options) {
 | |
|     return ChatCompletionStream.createChatCompletion(this._client.chat.completions, body, options);
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resources/beta/chat/chat.mjs
 | |
| var Chat2 = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.completions = new Completions2(this._client);
 | |
|   }
 | |
| };
 | |
| (function(Chat3) {
 | |
|   Chat3.Completions = Completions2;
 | |
| })(Chat2 || (Chat2 = {}));
 | |
| 
 | |
| // node_modules/openai/lib/AbstractAssistantStreamRunner.mjs
 | |
| var __classPrivateFieldSet5 = function(receiver, state, value, kind2, f) {
 | |
|   if (kind2 === "m")
 | |
|     throw new TypeError("Private method is not writable");
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a setter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|   return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
| };
 | |
| var __classPrivateFieldGet5 = function(receiver, state, kind2, f) {
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a getter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|   return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
| };
 | |
| var _AbstractAssistantStreamRunner_connectedPromise;
 | |
| var _AbstractAssistantStreamRunner_resolveConnectedPromise;
 | |
| var _AbstractAssistantStreamRunner_rejectConnectedPromise;
 | |
| var _AbstractAssistantStreamRunner_endPromise;
 | |
| var _AbstractAssistantStreamRunner_resolveEndPromise;
 | |
| var _AbstractAssistantStreamRunner_rejectEndPromise;
 | |
| var _AbstractAssistantStreamRunner_listeners;
 | |
| var _AbstractAssistantStreamRunner_ended;
 | |
| var _AbstractAssistantStreamRunner_errored;
 | |
| var _AbstractAssistantStreamRunner_aborted;
 | |
| var _AbstractAssistantStreamRunner_catchingPromiseCreated;
 | |
| var _AbstractAssistantStreamRunner_handleError;
 | |
| var AbstractAssistantStreamRunner = class {
 | |
|   constructor() {
 | |
|     this.controller = new AbortController();
 | |
|     _AbstractAssistantStreamRunner_connectedPromise.set(this, void 0);
 | |
|     _AbstractAssistantStreamRunner_resolveConnectedPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractAssistantStreamRunner_rejectConnectedPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractAssistantStreamRunner_endPromise.set(this, void 0);
 | |
|     _AbstractAssistantStreamRunner_resolveEndPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractAssistantStreamRunner_rejectEndPromise.set(this, () => {
 | |
|     });
 | |
|     _AbstractAssistantStreamRunner_listeners.set(this, {});
 | |
|     _AbstractAssistantStreamRunner_ended.set(this, false);
 | |
|     _AbstractAssistantStreamRunner_errored.set(this, false);
 | |
|     _AbstractAssistantStreamRunner_aborted.set(this, false);
 | |
|     _AbstractAssistantStreamRunner_catchingPromiseCreated.set(this, false);
 | |
|     _AbstractAssistantStreamRunner_handleError.set(this, (error) => {
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_errored, true, "f");
 | |
|       if (error instanceof Error && error.name === "AbortError") {
 | |
|         error = new APIUserAbortError();
 | |
|       }
 | |
|       if (error instanceof APIUserAbortError) {
 | |
|         __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_aborted, true, "f");
 | |
|         return this._emit("abort", error);
 | |
|       }
 | |
|       if (error instanceof OpenAIError) {
 | |
|         return this._emit("error", error);
 | |
|       }
 | |
|       if (error instanceof Error) {
 | |
|         const openAIError = new OpenAIError(error.message);
 | |
|         openAIError.cause = error;
 | |
|         return this._emit("error", openAIError);
 | |
|       }
 | |
|       return this._emit("error", new OpenAIError(String(error)));
 | |
|     });
 | |
|     __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_connectedPromise, new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_resolveConnectedPromise, resolve, "f");
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, reject, "f");
 | |
|     }), "f");
 | |
|     __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_endPromise, new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_resolveEndPromise, resolve, "f");
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, reject, "f");
 | |
|     }), "f");
 | |
|     __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_connectedPromise, "f").catch(() => {
 | |
|     });
 | |
|     __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_endPromise, "f").catch(() => {
 | |
|     });
 | |
|   }
 | |
|   _run(executor) {
 | |
|     setTimeout(() => {
 | |
|       executor().then(() => {
 | |
|         this._emit("end");
 | |
|       }, __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_handleError, "f"));
 | |
|     }, 0);
 | |
|   }
 | |
|   _addRun(run2) {
 | |
|     return run2;
 | |
|   }
 | |
|   _connected() {
 | |
|     if (this.ended)
 | |
|       return;
 | |
|     __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_resolveConnectedPromise, "f").call(this);
 | |
|     this._emit("connect");
 | |
|   }
 | |
|   get ended() {
 | |
|     return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_ended, "f");
 | |
|   }
 | |
|   get errored() {
 | |
|     return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_errored, "f");
 | |
|   }
 | |
|   get aborted() {
 | |
|     return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_aborted, "f");
 | |
|   }
 | |
|   abort() {
 | |
|     this.controller.abort();
 | |
|   }
 | |
|   on(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] || (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = []);
 | |
|     listeners.push({ listener });
 | |
|     return this;
 | |
|   }
 | |
|   off(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event];
 | |
|     if (!listeners)
 | |
|       return this;
 | |
|     const index = listeners.findIndex((l) => l.listener === listener);
 | |
|     if (index >= 0)
 | |
|       listeners.splice(index, 1);
 | |
|     return this;
 | |
|   }
 | |
|   once(event, listener) {
 | |
|     const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] || (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = []);
 | |
|     listeners.push({ listener, once: true });
 | |
|     return this;
 | |
|   }
 | |
|   emitted(event) {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, true, "f");
 | |
|       if (event !== "error")
 | |
|         this.once("error", reject);
 | |
|       this.once(event, resolve);
 | |
|     });
 | |
|   }
 | |
|   async done() {
 | |
|     __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, true, "f");
 | |
|     await __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_endPromise, "f");
 | |
|   }
 | |
|   _emit(event, ...args) {
 | |
|     if (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_ended, "f")) {
 | |
|       return;
 | |
|     }
 | |
|     if (event === "end") {
 | |
|       __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_ended, true, "f");
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_resolveEndPromise, "f").call(this);
 | |
|     }
 | |
|     const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event];
 | |
|     if (listeners) {
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = listeners.filter((l) => !l.once);
 | |
|       listeners.forEach(({ listener }) => listener(...args));
 | |
|     }
 | |
|     if (event === "abort") {
 | |
|       const error = args[0];
 | |
|       if (!__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, "f") && !listeners?.length) {
 | |
|         Promise.reject(error);
 | |
|       }
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, "f").call(this, error);
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, "f").call(this, error);
 | |
|       this._emit("end");
 | |
|       return;
 | |
|     }
 | |
|     if (event === "error") {
 | |
|       const error = args[0];
 | |
|       if (!__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, "f") && !listeners?.length) {
 | |
|         Promise.reject(error);
 | |
|       }
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, "f").call(this, error);
 | |
|       __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, "f").call(this, error);
 | |
|       this._emit("end");
 | |
|     }
 | |
|   }
 | |
|   async _threadAssistantStream(body, thread, options) {
 | |
|     return await this._createThreadAssistantStream(thread, body, options);
 | |
|   }
 | |
|   async _runAssistantStream(threadId, runs, params, options) {
 | |
|     return await this._createAssistantStream(runs, threadId, params, options);
 | |
|   }
 | |
|   async _runToolAssistantStream(threadId, runId, runs, params, options) {
 | |
|     return await this._createToolAssistantStream(runs, threadId, runId, params, options);
 | |
|   }
 | |
|   async _createThreadAssistantStream(thread, body, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const runResult = await thread.createAndRun({ ...body, stream: false }, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     return this._addRun(runResult);
 | |
|   }
 | |
|   async _createToolAssistantStream(run2, threadId, runId, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const runResult = await run2.submitToolOutputs(threadId, runId, { ...params, stream: false }, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     return this._addRun(runResult);
 | |
|   }
 | |
|   async _createAssistantStream(run2, threadId, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const runResult = await run2.create(threadId, { ...params, stream: false }, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     return this._addRun(runResult);
 | |
|   }
 | |
| };
 | |
| _AbstractAssistantStreamRunner_connectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_resolveConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_rejectConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_endPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_resolveEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_rejectEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_listeners = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_ended = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_errored = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_aborted = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_catchingPromiseCreated = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_handleError = /* @__PURE__ */ new WeakMap();
 | |
| 
 | |
| // node_modules/openai/lib/AssistantStream.mjs
 | |
| var __classPrivateFieldGet6 = function(receiver, state, kind2, f) {
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a getter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot read private member from an object whose class did not declare it");
 | |
|   return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
 | |
| };
 | |
| var __classPrivateFieldSet6 = function(receiver, state, value, kind2, f) {
 | |
|   if (kind2 === "m")
 | |
|     throw new TypeError("Private method is not writable");
 | |
|   if (kind2 === "a" && !f)
 | |
|     throw new TypeError("Private accessor was defined without a setter");
 | |
|   if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
 | |
|     throw new TypeError("Cannot write private member to an object whose class did not declare it");
 | |
|   return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
 | |
| };
 | |
| var _AssistantStream_instances;
 | |
| var _AssistantStream_events;
 | |
| var _AssistantStream_runStepSnapshots;
 | |
| var _AssistantStream_messageSnapshots;
 | |
| var _AssistantStream_messageSnapshot;
 | |
| var _AssistantStream_finalRun;
 | |
| var _AssistantStream_currentContentIndex;
 | |
| var _AssistantStream_currentContent;
 | |
| var _AssistantStream_currentToolCallIndex;
 | |
| var _AssistantStream_currentToolCall;
 | |
| var _AssistantStream_currentEvent;
 | |
| var _AssistantStream_currentRunSnapshot;
 | |
| var _AssistantStream_currentRunStepSnapshot;
 | |
| var _AssistantStream_addEvent;
 | |
| var _AssistantStream_endRequest;
 | |
| var _AssistantStream_handleMessage;
 | |
| var _AssistantStream_handleRunStep;
 | |
| var _AssistantStream_handleEvent;
 | |
| var _AssistantStream_accumulateRunStep;
 | |
| var _AssistantStream_accumulateMessage;
 | |
| var _AssistantStream_accumulateContent;
 | |
| var _AssistantStream_handleRun;
 | |
| var AssistantStream = class extends AbstractAssistantStreamRunner {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     _AssistantStream_instances.add(this);
 | |
|     _AssistantStream_events.set(this, []);
 | |
|     _AssistantStream_runStepSnapshots.set(this, {});
 | |
|     _AssistantStream_messageSnapshots.set(this, {});
 | |
|     _AssistantStream_messageSnapshot.set(this, void 0);
 | |
|     _AssistantStream_finalRun.set(this, void 0);
 | |
|     _AssistantStream_currentContentIndex.set(this, void 0);
 | |
|     _AssistantStream_currentContent.set(this, void 0);
 | |
|     _AssistantStream_currentToolCallIndex.set(this, void 0);
 | |
|     _AssistantStream_currentToolCall.set(this, void 0);
 | |
|     _AssistantStream_currentEvent.set(this, void 0);
 | |
|     _AssistantStream_currentRunSnapshot.set(this, void 0);
 | |
|     _AssistantStream_currentRunStepSnapshot.set(this, void 0);
 | |
|   }
 | |
|   [(_AssistantStream_events = /* @__PURE__ */ new WeakMap(), _AssistantStream_runStepSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_finalRun = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContentIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCallIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCall = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentEvent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunStepSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_instances = /* @__PURE__ */ new WeakSet(), Symbol.asyncIterator)]() {
 | |
|     const pushQueue = [];
 | |
|     const readQueue = [];
 | |
|     let done = false;
 | |
|     this.on("event", (event) => {
 | |
|       const reader = readQueue.shift();
 | |
|       if (reader) {
 | |
|         reader.resolve(event);
 | |
|       } else {
 | |
|         pushQueue.push(event);
 | |
|       }
 | |
|     });
 | |
|     this.on("end", () => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.resolve(void 0);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     this.on("abort", (err) => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.reject(err);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     this.on("error", (err) => {
 | |
|       done = true;
 | |
|       for (const reader of readQueue) {
 | |
|         reader.reject(err);
 | |
|       }
 | |
|       readQueue.length = 0;
 | |
|     });
 | |
|     return {
 | |
|       next: async () => {
 | |
|         if (!pushQueue.length) {
 | |
|           if (done) {
 | |
|             return { value: void 0, done: true };
 | |
|           }
 | |
|           return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
 | |
|         }
 | |
|         const chunk = pushQueue.shift();
 | |
|         return { value: chunk, done: false };
 | |
|       },
 | |
|       return: async () => {
 | |
|         this.abort();
 | |
|         return { value: void 0, done: true };
 | |
|       }
 | |
|     };
 | |
|   }
 | |
|   static fromReadableStream(stream) {
 | |
|     const runner = new AssistantStream();
 | |
|     runner._run(() => runner._fromReadableStream(stream));
 | |
|     return runner;
 | |
|   }
 | |
|   async _fromReadableStream(readableStream, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     this._connected();
 | |
|     const stream = Stream.fromReadableStream(readableStream, this.controller);
 | |
|     for await (const event of stream) {
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
 | |
|   }
 | |
|   toReadableStream() {
 | |
|     const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
 | |
|     return stream.toReadableStream();
 | |
|   }
 | |
|   static createToolAssistantStream(threadId, runId, runs, body, options) {
 | |
|     const runner = new AssistantStream();
 | |
|     runner._run(() => runner._runToolAssistantStream(threadId, runId, runs, body, {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" }
 | |
|     }));
 | |
|     return runner;
 | |
|   }
 | |
|   async _createToolAssistantStream(run2, threadId, runId, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const body = { ...params, stream: true };
 | |
|     const stream = await run2.submitToolOutputs(threadId, runId, body, {
 | |
|       ...options,
 | |
|       signal: this.controller.signal
 | |
|     });
 | |
|     this._connected();
 | |
|     for await (const event of stream) {
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
 | |
|   }
 | |
|   static createThreadAssistantStream(body, thread, options) {
 | |
|     const runner = new AssistantStream();
 | |
|     runner._run(() => runner._threadAssistantStream(body, thread, {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" }
 | |
|     }));
 | |
|     return runner;
 | |
|   }
 | |
|   static createAssistantStream(threadId, runs, params, options) {
 | |
|     const runner = new AssistantStream();
 | |
|     runner._run(() => runner._runAssistantStream(threadId, runs, params, {
 | |
|       ...options,
 | |
|       headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" }
 | |
|     }));
 | |
|     return runner;
 | |
|   }
 | |
|   currentEvent() {
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_currentEvent, "f");
 | |
|   }
 | |
|   currentRun() {
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_currentRunSnapshot, "f");
 | |
|   }
 | |
|   currentMessageSnapshot() {
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f");
 | |
|   }
 | |
|   currentRunStepSnapshot() {
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_currentRunStepSnapshot, "f");
 | |
|   }
 | |
|   async finalRunSteps() {
 | |
|     await this.done();
 | |
|     return Object.values(__classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f"));
 | |
|   }
 | |
|   async finalMessages() {
 | |
|     await this.done();
 | |
|     return Object.values(__classPrivateFieldGet6(this, _AssistantStream_messageSnapshots, "f"));
 | |
|   }
 | |
|   async finalRun() {
 | |
|     await this.done();
 | |
|     if (!__classPrivateFieldGet6(this, _AssistantStream_finalRun, "f"))
 | |
|       throw Error("Final run was not received.");
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_finalRun, "f");
 | |
|   }
 | |
|   async _createThreadAssistantStream(thread, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const body = { ...params, stream: true };
 | |
|     const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     for await (const event of stream) {
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
 | |
|   }
 | |
|   async _createAssistantStream(run2, threadId, params, options) {
 | |
|     const signal = options?.signal;
 | |
|     if (signal) {
 | |
|       if (signal.aborted)
 | |
|         this.controller.abort();
 | |
|       signal.addEventListener("abort", () => this.controller.abort());
 | |
|     }
 | |
|     const body = { ...params, stream: true };
 | |
|     const stream = await run2.create(threadId, body, { ...options, signal: this.controller.signal });
 | |
|     this._connected();
 | |
|     for await (const event of stream) {
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
 | |
|     }
 | |
|     if (stream.controller.signal?.aborted) {
 | |
|       throw new APIUserAbortError();
 | |
|     }
 | |
|     return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
 | |
|   }
 | |
|   static accumulateDelta(acc, delta) {
 | |
|     for (const [key, deltaValue] of Object.entries(delta)) {
 | |
|       if (!acc.hasOwnProperty(key)) {
 | |
|         acc[key] = deltaValue;
 | |
|         continue;
 | |
|       }
 | |
|       let accValue = acc[key];
 | |
|       if (accValue === null || accValue === void 0) {
 | |
|         acc[key] = deltaValue;
 | |
|         continue;
 | |
|       }
 | |
|       if (key === "index" || key === "type") {
 | |
|         acc[key] = deltaValue;
 | |
|         continue;
 | |
|       }
 | |
|       if (typeof accValue === "string" && typeof deltaValue === "string") {
 | |
|         accValue += deltaValue;
 | |
|       } else if (typeof accValue === "number" && typeof deltaValue === "number") {
 | |
|         accValue += deltaValue;
 | |
|       } else if (isObj(accValue) && isObj(deltaValue)) {
 | |
|         accValue = this.accumulateDelta(accValue, deltaValue);
 | |
|       } else if (Array.isArray(accValue) && Array.isArray(deltaValue)) {
 | |
|         if (accValue.every((x) => typeof x === "string" || typeof x === "number")) {
 | |
|           accValue.push(...deltaValue);
 | |
|           continue;
 | |
|         }
 | |
|       } else {
 | |
|         throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`);
 | |
|       }
 | |
|       acc[key] = accValue;
 | |
|     }
 | |
|     return acc;
 | |
|   }
 | |
| };
 | |
| _AssistantStream_addEvent = function _AssistantStream_addEvent2(event) {
 | |
|   if (this.ended)
 | |
|     return;
 | |
|   __classPrivateFieldSet6(this, _AssistantStream_currentEvent, event, "f");
 | |
|   __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleEvent).call(this, event);
 | |
|   switch (event.event) {
 | |
|     case "thread.created":
 | |
|       break;
 | |
|     case "thread.run.created":
 | |
|     case "thread.run.queued":
 | |
|     case "thread.run.in_progress":
 | |
|     case "thread.run.requires_action":
 | |
|     case "thread.run.completed":
 | |
|     case "thread.run.failed":
 | |
|     case "thread.run.cancelling":
 | |
|     case "thread.run.cancelled":
 | |
|     case "thread.run.expired":
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleRun).call(this, event);
 | |
|       break;
 | |
|     case "thread.run.step.created":
 | |
|     case "thread.run.step.in_progress":
 | |
|     case "thread.run.step.delta":
 | |
|     case "thread.run.step.completed":
 | |
|     case "thread.run.step.failed":
 | |
|     case "thread.run.step.cancelled":
 | |
|     case "thread.run.step.expired":
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleRunStep).call(this, event);
 | |
|       break;
 | |
|     case "thread.message.created":
 | |
|     case "thread.message.in_progress":
 | |
|     case "thread.message.delta":
 | |
|     case "thread.message.completed":
 | |
|     case "thread.message.incomplete":
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleMessage).call(this, event);
 | |
|       break;
 | |
|     case "error":
 | |
|       throw new Error("Encountered an error event in event processing - errors should be processed earlier");
 | |
|   }
 | |
| }, _AssistantStream_endRequest = function _AssistantStream_endRequest2() {
 | |
|   if (this.ended) {
 | |
|     throw new OpenAIError(`stream has ended, this shouldn't happen`);
 | |
|   }
 | |
|   if (!__classPrivateFieldGet6(this, _AssistantStream_finalRun, "f"))
 | |
|     throw Error("Final run has not been received");
 | |
|   return __classPrivateFieldGet6(this, _AssistantStream_finalRun, "f");
 | |
| }, _AssistantStream_handleMessage = function _AssistantStream_handleMessage2(event) {
 | |
|   const [accumulatedMessage, newContent] = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateMessage).call(this, event, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"));
 | |
|   __classPrivateFieldSet6(this, _AssistantStream_messageSnapshot, accumulatedMessage, "f");
 | |
|   __classPrivateFieldGet6(this, _AssistantStream_messageSnapshots, "f")[accumulatedMessage.id] = accumulatedMessage;
 | |
|   for (const content of newContent) {
 | |
|     const snapshotContent = accumulatedMessage.content[content.index];
 | |
|     if (snapshotContent?.type == "text") {
 | |
|       this._emit("textCreated", snapshotContent.text);
 | |
|     }
 | |
|   }
 | |
|   switch (event.event) {
 | |
|     case "thread.message.created":
 | |
|       this._emit("messageCreated", event.data);
 | |
|       break;
 | |
|     case "thread.message.in_progress":
 | |
|       break;
 | |
|     case "thread.message.delta":
 | |
|       this._emit("messageDelta", event.data.delta, accumulatedMessage);
 | |
|       if (event.data.delta.content) {
 | |
|         for (const content of event.data.delta.content) {
 | |
|           if (content.type == "text" && content.text) {
 | |
|             let textDelta = content.text;
 | |
|             let snapshot = accumulatedMessage.content[content.index];
 | |
|             if (snapshot && snapshot.type == "text") {
 | |
|               this._emit("textDelta", textDelta, snapshot.text);
 | |
|             } else {
 | |
|               throw Error("The snapshot associated with this text delta is not text or missing");
 | |
|             }
 | |
|           }
 | |
|           if (content.index != __classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f")) {
 | |
|             if (__classPrivateFieldGet6(this, _AssistantStream_currentContent, "f")) {
 | |
|               switch (__classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").type) {
 | |
|                 case "text":
 | |
|                   this._emit("textDone", __classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").text, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"));
 | |
|                   break;
 | |
|                 case "image_file":
 | |
|                   this._emit("imageFileDone", __classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").image_file, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"));
 | |
|                   break;
 | |
|               }
 | |
|             }
 | |
|             __classPrivateFieldSet6(this, _AssistantStream_currentContentIndex, content.index, "f");
 | |
|           }
 | |
|           __classPrivateFieldSet6(this, _AssistantStream_currentContent, accumulatedMessage.content[content.index], "f");
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     case "thread.message.completed":
 | |
|     case "thread.message.incomplete":
 | |
|       if (__classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f") !== void 0) {
 | |
|         const currentContent = event.data.content[__classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f")];
 | |
|         if (currentContent) {
 | |
|           switch (currentContent.type) {
 | |
|             case "image_file":
 | |
|               this._emit("imageFileDone", currentContent.image_file, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"));
 | |
|               break;
 | |
|             case "text":
 | |
|               this._emit("textDone", currentContent.text, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"));
 | |
|               break;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if (__classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")) {
 | |
|         this._emit("messageDone", event.data);
 | |
|       }
 | |
|       __classPrivateFieldSet6(this, _AssistantStream_messageSnapshot, void 0, "f");
 | |
|   }
 | |
| }, _AssistantStream_handleRunStep = function _AssistantStream_handleRunStep2(event) {
 | |
|   const accumulatedRunStep = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateRunStep).call(this, event);
 | |
|   __classPrivateFieldSet6(this, _AssistantStream_currentRunStepSnapshot, accumulatedRunStep, "f");
 | |
|   switch (event.event) {
 | |
|     case "thread.run.step.created":
 | |
|       this._emit("runStepCreated", event.data);
 | |
|       break;
 | |
|     case "thread.run.step.delta":
 | |
|       const delta = event.data.delta;
 | |
|       if (delta.step_details && delta.step_details.type == "tool_calls" && delta.step_details.tool_calls && accumulatedRunStep.step_details.type == "tool_calls") {
 | |
|         for (const toolCall of delta.step_details.tool_calls) {
 | |
|           if (toolCall.index == __classPrivateFieldGet6(this, _AssistantStream_currentToolCallIndex, "f")) {
 | |
|             this._emit("toolCallDelta", toolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]);
 | |
|           } else {
 | |
|             if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) {
 | |
|               this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f"));
 | |
|             }
 | |
|             __classPrivateFieldSet6(this, _AssistantStream_currentToolCallIndex, toolCall.index, "f");
 | |
|             __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index], "f");
 | |
|             if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f"))
 | |
|               this._emit("toolCallCreated", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f"));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       this._emit("runStepDelta", event.data.delta, accumulatedRunStep);
 | |
|       break;
 | |
|     case "thread.run.step.completed":
 | |
|     case "thread.run.step.failed":
 | |
|     case "thread.run.step.cancelled":
 | |
|     case "thread.run.step.expired":
 | |
|       __classPrivateFieldSet6(this, _AssistantStream_currentRunStepSnapshot, void 0, "f");
 | |
|       const details = event.data.step_details;
 | |
|       if (details.type == "tool_calls") {
 | |
|         if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) {
 | |
|           this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f"));
 | |
|           __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, void 0, "f");
 | |
|         }
 | |
|       }
 | |
|       this._emit("runStepDone", event.data, accumulatedRunStep);
 | |
|       break;
 | |
|     case "thread.run.step.in_progress":
 | |
|       break;
 | |
|   }
 | |
| }, _AssistantStream_handleEvent = function _AssistantStream_handleEvent2(event) {
 | |
|   __classPrivateFieldGet6(this, _AssistantStream_events, "f").push(event);
 | |
|   this._emit("event", event);
 | |
| }, _AssistantStream_accumulateRunStep = function _AssistantStream_accumulateRunStep2(event) {
 | |
|   switch (event.event) {
 | |
|     case "thread.run.step.created":
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data;
 | |
|       return event.data;
 | |
|     case "thread.run.step.delta":
 | |
|       let snapshot = __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
 | |
|       if (!snapshot) {
 | |
|         throw Error("Received a RunStepDelta before creation of a snapshot");
 | |
|       }
 | |
|       let data = event.data;
 | |
|       if (data.delta) {
 | |
|         const accumulated = AssistantStream.accumulateDelta(snapshot, data.delta);
 | |
|         __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = accumulated;
 | |
|       }
 | |
|       return __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
 | |
|     case "thread.run.step.completed":
 | |
|     case "thread.run.step.failed":
 | |
|     case "thread.run.step.cancelled":
 | |
|     case "thread.run.step.expired":
 | |
|     case "thread.run.step.in_progress":
 | |
|       __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data;
 | |
|       break;
 | |
|   }
 | |
|   if (__classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id])
 | |
|     return __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
 | |
|   throw new Error("No snapshot available");
 | |
| }, _AssistantStream_accumulateMessage = function _AssistantStream_accumulateMessage2(event, snapshot) {
 | |
|   let newContent = [];
 | |
|   switch (event.event) {
 | |
|     case "thread.message.created":
 | |
|       return [event.data, newContent];
 | |
|     case "thread.message.delta":
 | |
|       if (!snapshot) {
 | |
|         throw Error("Received a delta with no existing snapshot (there should be one from message creation)");
 | |
|       }
 | |
|       let data = event.data;
 | |
|       if (data.delta.content) {
 | |
|         for (const contentElement of data.delta.content) {
 | |
|           if (contentElement.index in snapshot.content) {
 | |
|             let currentContent = snapshot.content[contentElement.index];
 | |
|             snapshot.content[contentElement.index] = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateContent).call(this, contentElement, currentContent);
 | |
|           } else {
 | |
|             snapshot.content[contentElement.index] = contentElement;
 | |
|             newContent.push(contentElement);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       return [snapshot, newContent];
 | |
|     case "thread.message.in_progress":
 | |
|     case "thread.message.completed":
 | |
|     case "thread.message.incomplete":
 | |
|       if (snapshot) {
 | |
|         return [snapshot, newContent];
 | |
|       } else {
 | |
|         throw Error("Received thread message event with no existing snapshot");
 | |
|       }
 | |
|   }
 | |
|   throw Error("Tried to accumulate a non-message event");
 | |
| }, _AssistantStream_accumulateContent = function _AssistantStream_accumulateContent2(contentElement, currentContent) {
 | |
|   return AssistantStream.accumulateDelta(currentContent, contentElement);
 | |
| }, _AssistantStream_handleRun = function _AssistantStream_handleRun2(event) {
 | |
|   __classPrivateFieldSet6(this, _AssistantStream_currentRunSnapshot, event.data, "f");
 | |
|   switch (event.event) {
 | |
|     case "thread.run.created":
 | |
|       break;
 | |
|     case "thread.run.queued":
 | |
|       break;
 | |
|     case "thread.run.in_progress":
 | |
|       break;
 | |
|     case "thread.run.requires_action":
 | |
|     case "thread.run.cancelled":
 | |
|     case "thread.run.failed":
 | |
|     case "thread.run.completed":
 | |
|     case "thread.run.expired":
 | |
|       __classPrivateFieldSet6(this, _AssistantStream_finalRun, event.data, "f");
 | |
|       if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) {
 | |
|         this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f"));
 | |
|         __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, void 0, "f");
 | |
|       }
 | |
|       break;
 | |
|     case "thread.run.cancelling":
 | |
|       break;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resources/beta/threads/messages.mjs
 | |
| var Messages = class extends APIResource {
 | |
|   create(threadId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}/messages`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(threadId, messageId, options) {
 | |
|     return this._client.get(`/threads/${threadId}/messages/${messageId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   update(threadId, messageId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}/messages/${messageId}`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(threadId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list(threadId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/threads/${threadId}/messages`, MessagesPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   del(threadId, messageId, options) {
 | |
|     return this._client.delete(`/threads/${threadId}/messages/${messageId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var MessagesPage = class extends CursorPage {
 | |
| };
 | |
| (function(Messages2) {
 | |
|   Messages2.MessagesPage = MessagesPage;
 | |
| })(Messages || (Messages = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/threads/runs/steps.mjs
 | |
| var Steps = class extends APIResource {
 | |
|   retrieve(threadId, runId, stepId, options) {
 | |
|     return this._client.get(`/threads/${threadId}/runs/${runId}/steps/${stepId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(threadId, runId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list(threadId, runId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/threads/${threadId}/runs/${runId}/steps`, RunStepsPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var RunStepsPage = class extends CursorPage {
 | |
| };
 | |
| (function(Steps2) {
 | |
|   Steps2.RunStepsPage = RunStepsPage;
 | |
| })(Steps || (Steps = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/threads/runs/runs.mjs
 | |
| var Runs = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.steps = new Steps(this._client);
 | |
|   }
 | |
|   create(threadId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}/runs`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers },
 | |
|       stream: body.stream ?? false
 | |
|     });
 | |
|   }
 | |
|   retrieve(threadId, runId, options) {
 | |
|     return this._client.get(`/threads/${threadId}/runs/${runId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   update(threadId, runId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}/runs/${runId}`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(threadId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list(threadId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/threads/${threadId}/runs`, RunsPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   cancel(threadId, runId, options) {
 | |
|     return this._client.post(`/threads/${threadId}/runs/${runId}/cancel`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   async createAndPoll(threadId, body, options) {
 | |
|     const run2 = await this.create(threadId, body, options);
 | |
|     return await this.poll(threadId, run2.id, options);
 | |
|   }
 | |
|   createAndStream(threadId, body, options) {
 | |
|     return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options);
 | |
|   }
 | |
|   async poll(threadId, runId, options) {
 | |
|     const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" };
 | |
|     if (options?.pollIntervalMs) {
 | |
|       headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
 | |
|     }
 | |
|     while (true) {
 | |
|       const { data: run2, response } = await this.retrieve(threadId, runId, {
 | |
|         ...options,
 | |
|         headers: { ...options?.headers, ...headers }
 | |
|       }).withResponse();
 | |
|       switch (run2.status) {
 | |
|         case "queued":
 | |
|         case "in_progress":
 | |
|         case "cancelling":
 | |
|           let sleepInterval = 5e3;
 | |
|           if (options?.pollIntervalMs) {
 | |
|             sleepInterval = options.pollIntervalMs;
 | |
|           } else {
 | |
|             const headerInterval = response.headers.get("openai-poll-after-ms");
 | |
|             if (headerInterval) {
 | |
|               const headerIntervalMs = parseInt(headerInterval);
 | |
|               if (!isNaN(headerIntervalMs)) {
 | |
|                 sleepInterval = headerIntervalMs;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           await sleep(sleepInterval);
 | |
|           break;
 | |
|         case "requires_action":
 | |
|         case "incomplete":
 | |
|         case "cancelled":
 | |
|         case "completed":
 | |
|         case "failed":
 | |
|         case "expired":
 | |
|           return run2;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   stream(threadId, body, options) {
 | |
|     return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options);
 | |
|   }
 | |
|   submitToolOutputs(threadId, runId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}/runs/${runId}/submit_tool_outputs`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers },
 | |
|       stream: body.stream ?? false
 | |
|     });
 | |
|   }
 | |
|   async submitToolOutputsAndPoll(threadId, runId, body, options) {
 | |
|     const run2 = await this.submitToolOutputs(threadId, runId, body, options);
 | |
|     return await this.poll(threadId, run2.id, options);
 | |
|   }
 | |
|   submitToolOutputsStream(threadId, runId, body, options) {
 | |
|     return AssistantStream.createToolAssistantStream(threadId, runId, this._client.beta.threads.runs, body, options);
 | |
|   }
 | |
| };
 | |
| var RunsPage = class extends CursorPage {
 | |
| };
 | |
| (function(Runs2) {
 | |
|   Runs2.RunsPage = RunsPage;
 | |
|   Runs2.Steps = Steps;
 | |
|   Runs2.RunStepsPage = RunStepsPage;
 | |
| })(Runs || (Runs = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/threads/threads.mjs
 | |
| var Threads = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.runs = new Runs(this._client);
 | |
|     this.messages = new Messages(this._client);
 | |
|   }
 | |
|   create(body = {}, options) {
 | |
|     if (isRequestOptions(body)) {
 | |
|       return this.create({}, body);
 | |
|     }
 | |
|     return this._client.post("/threads", {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(threadId, options) {
 | |
|     return this._client.get(`/threads/${threadId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   update(threadId, body, options) {
 | |
|     return this._client.post(`/threads/${threadId}`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   del(threadId, options) {
 | |
|     return this._client.delete(`/threads/${threadId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   createAndRun(body, options) {
 | |
|     return this._client.post("/threads/runs", {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers },
 | |
|       stream: body.stream ?? false
 | |
|     });
 | |
|   }
 | |
|   async createAndRunPoll(body, options) {
 | |
|     const run2 = await this.createAndRun(body, options);
 | |
|     return await this.runs.poll(run2.thread_id, run2.id, options);
 | |
|   }
 | |
|   createAndRunStream(body, options) {
 | |
|     return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options);
 | |
|   }
 | |
| };
 | |
| (function(Threads2) {
 | |
|   Threads2.Runs = Runs;
 | |
|   Threads2.RunsPage = RunsPage;
 | |
|   Threads2.Messages = Messages;
 | |
|   Threads2.MessagesPage = MessagesPage;
 | |
| })(Threads || (Threads = {}));
 | |
| 
 | |
| // node_modules/openai/lib/Util.mjs
 | |
| var allSettledWithThrow = async (promises) => {
 | |
|   const results = await Promise.allSettled(promises);
 | |
|   const rejected = results.filter((result) => result.status === "rejected");
 | |
|   if (rejected.length) {
 | |
|     for (const result of rejected) {
 | |
|       console.error(result.reason);
 | |
|     }
 | |
|     throw new Error(`${rejected.length} promise(s) failed - see the above errors`);
 | |
|   }
 | |
|   const values = [];
 | |
|   for (const result of results) {
 | |
|     if (result.status === "fulfilled") {
 | |
|       values.push(result.value);
 | |
|     }
 | |
|   }
 | |
|   return values;
 | |
| };
 | |
| 
 | |
| // node_modules/openai/resources/beta/vector-stores/files.mjs
 | |
| var Files = class extends APIResource {
 | |
|   create(vectorStoreId, body, options) {
 | |
|     return this._client.post(`/vector_stores/${vectorStoreId}/files`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(vectorStoreId, fileId, options) {
 | |
|     return this._client.get(`/vector_stores/${vectorStoreId}/files/${fileId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(vectorStoreId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list(vectorStoreId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/vector_stores/${vectorStoreId}/files`, VectorStoreFilesPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   del(vectorStoreId, fileId, options) {
 | |
|     return this._client.delete(`/vector_stores/${vectorStoreId}/files/${fileId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   async createAndPoll(vectorStoreId, body, options) {
 | |
|     const file = await this.create(vectorStoreId, body, options);
 | |
|     return await this.poll(vectorStoreId, file.id, options);
 | |
|   }
 | |
|   async poll(vectorStoreId, fileId, options) {
 | |
|     const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" };
 | |
|     if (options?.pollIntervalMs) {
 | |
|       headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
 | |
|     }
 | |
|     while (true) {
 | |
|       const fileResponse = await this.retrieve(vectorStoreId, fileId, {
 | |
|         ...options,
 | |
|         headers
 | |
|       }).withResponse();
 | |
|       const file = fileResponse.data;
 | |
|       switch (file.status) {
 | |
|         case "in_progress":
 | |
|           let sleepInterval = 5e3;
 | |
|           if (options?.pollIntervalMs) {
 | |
|             sleepInterval = options.pollIntervalMs;
 | |
|           } else {
 | |
|             const headerInterval = fileResponse.response.headers.get("openai-poll-after-ms");
 | |
|             if (headerInterval) {
 | |
|               const headerIntervalMs = parseInt(headerInterval);
 | |
|               if (!isNaN(headerIntervalMs)) {
 | |
|                 sleepInterval = headerIntervalMs;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           await sleep(sleepInterval);
 | |
|           break;
 | |
|         case "failed":
 | |
|         case "completed":
 | |
|           return file;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   async upload(vectorStoreId, file, options) {
 | |
|     const fileInfo = await this._client.files.create({ file, purpose: "assistants" }, options);
 | |
|     return this.create(vectorStoreId, { file_id: fileInfo.id }, options);
 | |
|   }
 | |
|   async uploadAndPoll(vectorStoreId, file, options) {
 | |
|     const fileInfo = await this.upload(vectorStoreId, file, options);
 | |
|     return await this.poll(vectorStoreId, fileInfo.id, options);
 | |
|   }
 | |
| };
 | |
| var VectorStoreFilesPage = class extends CursorPage {
 | |
| };
 | |
| (function(Files3) {
 | |
|   Files3.VectorStoreFilesPage = VectorStoreFilesPage;
 | |
| })(Files || (Files = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/vector-stores/file-batches.mjs
 | |
| var FileBatches = class extends APIResource {
 | |
|   create(vectorStoreId, body, options) {
 | |
|     return this._client.post(`/vector_stores/${vectorStoreId}/file_batches`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(vectorStoreId, batchId, options) {
 | |
|     return this._client.get(`/vector_stores/${vectorStoreId}/file_batches/${batchId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   cancel(vectorStoreId, batchId, options) {
 | |
|     return this._client.post(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/cancel`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   async createAndPoll(vectorStoreId, body, options) {
 | |
|     const batch = await this.create(vectorStoreId, body);
 | |
|     return await this.poll(vectorStoreId, batch.id, options);
 | |
|   }
 | |
|   listFiles(vectorStoreId, batchId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.listFiles(vectorStoreId, batchId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/files`, VectorStoreFilesPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } });
 | |
|   }
 | |
|   async poll(vectorStoreId, batchId, options) {
 | |
|     const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" };
 | |
|     if (options?.pollIntervalMs) {
 | |
|       headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
 | |
|     }
 | |
|     while (true) {
 | |
|       const { data: batch, response } = await this.retrieve(vectorStoreId, batchId, {
 | |
|         ...options,
 | |
|         headers
 | |
|       }).withResponse();
 | |
|       switch (batch.status) {
 | |
|         case "in_progress":
 | |
|           let sleepInterval = 5e3;
 | |
|           if (options?.pollIntervalMs) {
 | |
|             sleepInterval = options.pollIntervalMs;
 | |
|           } else {
 | |
|             const headerInterval = response.headers.get("openai-poll-after-ms");
 | |
|             if (headerInterval) {
 | |
|               const headerIntervalMs = parseInt(headerInterval);
 | |
|               if (!isNaN(headerIntervalMs)) {
 | |
|                 sleepInterval = headerIntervalMs;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           await sleep(sleepInterval);
 | |
|           break;
 | |
|         case "failed":
 | |
|         case "cancelled":
 | |
|         case "completed":
 | |
|           return batch;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   async uploadAndPoll(vectorStoreId, { files, fileIds = [] }, options) {
 | |
|     if (files == null || files.length == 0) {
 | |
|       throw new Error(`No \`files\` provided to process. If you've already uploaded files you should use \`.createAndPoll()\` instead`);
 | |
|     }
 | |
|     const configuredConcurrency = options?.maxConcurrency ?? 5;
 | |
|     const concurrencyLimit = Math.min(configuredConcurrency, files.length);
 | |
|     const client = this._client;
 | |
|     const fileIterator = files.values();
 | |
|     const allFileIds = [...fileIds];
 | |
|     async function processFiles(iterator) {
 | |
|       for (let item of iterator) {
 | |
|         const fileObj = await client.files.create({ file: item, purpose: "assistants" }, options);
 | |
|         allFileIds.push(fileObj.id);
 | |
|       }
 | |
|     }
 | |
|     const workers = Array(concurrencyLimit).fill(fileIterator).map(processFiles);
 | |
|     await allSettledWithThrow(workers);
 | |
|     return await this.createAndPoll(vectorStoreId, {
 | |
|       file_ids: allFileIds
 | |
|     });
 | |
|   }
 | |
| };
 | |
| (function(FileBatches2) {
 | |
| })(FileBatches || (FileBatches = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/vector-stores/vector-stores.mjs
 | |
| var VectorStores = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.files = new Files(this._client);
 | |
|     this.fileBatches = new FileBatches(this._client);
 | |
|   }
 | |
|   create(body, options) {
 | |
|     return this._client.post("/vector_stores", {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   retrieve(vectorStoreId, options) {
 | |
|     return this._client.get(`/vector_stores/${vectorStoreId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   update(vectorStoreId, body, options) {
 | |
|     return this._client.post(`/vector_stores/${vectorStoreId}`, {
 | |
|       body,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   list(query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list({}, query);
 | |
|     }
 | |
|     return this._client.getAPIList("/vector_stores", VectorStoresPage, {
 | |
|       query,
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   del(vectorStoreId, options) {
 | |
|     return this._client.delete(`/vector_stores/${vectorStoreId}`, {
 | |
|       ...options,
 | |
|       headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var VectorStoresPage = class extends CursorPage {
 | |
| };
 | |
| (function(VectorStores2) {
 | |
|   VectorStores2.VectorStoresPage = VectorStoresPage;
 | |
|   VectorStores2.Files = Files;
 | |
|   VectorStores2.VectorStoreFilesPage = VectorStoreFilesPage;
 | |
|   VectorStores2.FileBatches = FileBatches;
 | |
| })(VectorStores || (VectorStores = {}));
 | |
| 
 | |
| // node_modules/openai/resources/beta/beta.mjs
 | |
| var Beta = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.vectorStores = new VectorStores(this._client);
 | |
|     this.chat = new Chat2(this._client);
 | |
|     this.assistants = new Assistants(this._client);
 | |
|     this.threads = new Threads(this._client);
 | |
|   }
 | |
| };
 | |
| (function(Beta2) {
 | |
|   Beta2.VectorStores = VectorStores;
 | |
|   Beta2.VectorStoresPage = VectorStoresPage;
 | |
|   Beta2.Chat = Chat2;
 | |
|   Beta2.Assistants = Assistants;
 | |
|   Beta2.AssistantsPage = AssistantsPage;
 | |
|   Beta2.Threads = Threads;
 | |
| })(Beta || (Beta = {}));
 | |
| 
 | |
| // node_modules/openai/resources/completions.mjs
 | |
| var Completions3 = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/completions", { body, ...options, stream: body.stream ?? false });
 | |
|   }
 | |
| };
 | |
| (function(Completions4) {
 | |
| })(Completions3 || (Completions3 = {}));
 | |
| 
 | |
| // node_modules/openai/resources/embeddings.mjs
 | |
| var Embeddings = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/embeddings", { body, ...options });
 | |
|   }
 | |
| };
 | |
| (function(Embeddings2) {
 | |
| })(Embeddings || (Embeddings = {}));
 | |
| 
 | |
| // node_modules/openai/resources/files.mjs
 | |
| var Files2 = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/files", multipartFormRequestOptions({ body, ...options }));
 | |
|   }
 | |
|   retrieve(fileId, options) {
 | |
|     return this._client.get(`/files/${fileId}`, options);
 | |
|   }
 | |
|   list(query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list({}, query);
 | |
|     }
 | |
|     return this._client.getAPIList("/files", FileObjectsPage, { query, ...options });
 | |
|   }
 | |
|   del(fileId, options) {
 | |
|     return this._client.delete(`/files/${fileId}`, options);
 | |
|   }
 | |
|   content(fileId, options) {
 | |
|     return this._client.get(`/files/${fileId}/content`, { ...options, __binaryResponse: true });
 | |
|   }
 | |
|   retrieveContent(fileId, options) {
 | |
|     return this._client.get(`/files/${fileId}/content`, {
 | |
|       ...options,
 | |
|       headers: { Accept: "application/json", ...options?.headers }
 | |
|     });
 | |
|   }
 | |
|   async waitForProcessing(id, { pollInterval = 5e3, maxWait = 30 * 60 * 1e3 } = {}) {
 | |
|     const TERMINAL_STATES = /* @__PURE__ */ new Set(["processed", "error", "deleted"]);
 | |
|     const start = Date.now();
 | |
|     let file = await this.retrieve(id);
 | |
|     while (!file.status || !TERMINAL_STATES.has(file.status)) {
 | |
|       await sleep(pollInterval);
 | |
|       file = await this.retrieve(id);
 | |
|       if (Date.now() - start > maxWait) {
 | |
|         throw new APIConnectionTimeoutError({
 | |
|           message: `Giving up on waiting for file ${id} to finish processing after ${maxWait} milliseconds.`
 | |
|         });
 | |
|       }
 | |
|     }
 | |
|     return file;
 | |
|   }
 | |
| };
 | |
| var FileObjectsPage = class extends Page {
 | |
| };
 | |
| (function(Files3) {
 | |
|   Files3.FileObjectsPage = FileObjectsPage;
 | |
| })(Files2 || (Files2 = {}));
 | |
| 
 | |
| // node_modules/openai/resources/fine-tuning/jobs/checkpoints.mjs
 | |
| var Checkpoints = class extends APIResource {
 | |
|   list(fineTuningJobId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list(fineTuningJobId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/checkpoints`, FineTuningJobCheckpointsPage, { query, ...options });
 | |
|   }
 | |
| };
 | |
| var FineTuningJobCheckpointsPage = class extends CursorPage {
 | |
| };
 | |
| (function(Checkpoints2) {
 | |
|   Checkpoints2.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage;
 | |
| })(Checkpoints || (Checkpoints = {}));
 | |
| 
 | |
| // node_modules/openai/resources/fine-tuning/jobs/jobs.mjs
 | |
| var Jobs = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.checkpoints = new Checkpoints(this._client);
 | |
|   }
 | |
|   create(body, options) {
 | |
|     return this._client.post("/fine_tuning/jobs", { body, ...options });
 | |
|   }
 | |
|   retrieve(fineTuningJobId, options) {
 | |
|     return this._client.get(`/fine_tuning/jobs/${fineTuningJobId}`, options);
 | |
|   }
 | |
|   list(query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.list({}, query);
 | |
|     }
 | |
|     return this._client.getAPIList("/fine_tuning/jobs", FineTuningJobsPage, { query, ...options });
 | |
|   }
 | |
|   cancel(fineTuningJobId, options) {
 | |
|     return this._client.post(`/fine_tuning/jobs/${fineTuningJobId}/cancel`, options);
 | |
|   }
 | |
|   listEvents(fineTuningJobId, query = {}, options) {
 | |
|     if (isRequestOptions(query)) {
 | |
|       return this.listEvents(fineTuningJobId, {}, query);
 | |
|     }
 | |
|     return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/events`, FineTuningJobEventsPage, {
 | |
|       query,
 | |
|       ...options
 | |
|     });
 | |
|   }
 | |
| };
 | |
| var FineTuningJobsPage = class extends CursorPage {
 | |
| };
 | |
| var FineTuningJobEventsPage = class extends CursorPage {
 | |
| };
 | |
| (function(Jobs2) {
 | |
|   Jobs2.FineTuningJobsPage = FineTuningJobsPage;
 | |
|   Jobs2.FineTuningJobEventsPage = FineTuningJobEventsPage;
 | |
|   Jobs2.Checkpoints = Checkpoints;
 | |
|   Jobs2.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage;
 | |
| })(Jobs || (Jobs = {}));
 | |
| 
 | |
| // node_modules/openai/resources/fine-tuning/fine-tuning.mjs
 | |
| var FineTuning = class extends APIResource {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.jobs = new Jobs(this._client);
 | |
|   }
 | |
| };
 | |
| (function(FineTuning2) {
 | |
|   FineTuning2.Jobs = Jobs;
 | |
|   FineTuning2.FineTuningJobsPage = FineTuningJobsPage;
 | |
|   FineTuning2.FineTuningJobEventsPage = FineTuningJobEventsPage;
 | |
| })(FineTuning || (FineTuning = {}));
 | |
| 
 | |
| // node_modules/openai/resources/images.mjs
 | |
| var Images = class extends APIResource {
 | |
|   createVariation(body, options) {
 | |
|     return this._client.post("/images/variations", multipartFormRequestOptions({ body, ...options }));
 | |
|   }
 | |
|   edit(body, options) {
 | |
|     return this._client.post("/images/edits", multipartFormRequestOptions({ body, ...options }));
 | |
|   }
 | |
|   generate(body, options) {
 | |
|     return this._client.post("/images/generations", { body, ...options });
 | |
|   }
 | |
| };
 | |
| (function(Images2) {
 | |
| })(Images || (Images = {}));
 | |
| 
 | |
| // node_modules/openai/resources/models.mjs
 | |
| var Models = class extends APIResource {
 | |
|   retrieve(model, options) {
 | |
|     return this._client.get(`/models/${model}`, options);
 | |
|   }
 | |
|   list(options) {
 | |
|     return this._client.getAPIList("/models", ModelsPage, options);
 | |
|   }
 | |
|   del(model, options) {
 | |
|     return this._client.delete(`/models/${model}`, options);
 | |
|   }
 | |
| };
 | |
| var ModelsPage = class extends Page {
 | |
| };
 | |
| (function(Models2) {
 | |
|   Models2.ModelsPage = ModelsPage;
 | |
| })(Models || (Models = {}));
 | |
| 
 | |
| // node_modules/openai/resources/moderations.mjs
 | |
| var Moderations = class extends APIResource {
 | |
|   create(body, options) {
 | |
|     return this._client.post("/moderations", { body, ...options });
 | |
|   }
 | |
| };
 | |
| (function(Moderations2) {
 | |
| })(Moderations || (Moderations = {}));
 | |
| 
 | |
| // node_modules/openai/index.mjs
 | |
| var _a;
 | |
| var OpenAI = class extends APIClient {
 | |
|   constructor({ baseURL = readEnv("OPENAI_BASE_URL"), apiKey = readEnv("OPENAI_API_KEY"), organization = readEnv("OPENAI_ORG_ID") ?? null, project = readEnv("OPENAI_PROJECT_ID") ?? null, ...opts } = {}) {
 | |
|     if (apiKey === void 0) {
 | |
|       throw new OpenAIError("The OPENAI_API_KEY environment variable is missing or empty; either provide it, or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'My API Key' }).");
 | |
|     }
 | |
|     const options = {
 | |
|       apiKey,
 | |
|       organization,
 | |
|       project,
 | |
|       ...opts,
 | |
|       baseURL: baseURL || `https://api.openai.com/v1`
 | |
|     };
 | |
|     if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) {
 | |
|       throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n");
 | |
|     }
 | |
|     super({
 | |
|       baseURL: options.baseURL,
 | |
|       timeout: options.timeout ?? 6e5,
 | |
|       httpAgent: options.httpAgent,
 | |
|       maxRetries: options.maxRetries,
 | |
|       fetch: options.fetch
 | |
|     });
 | |
|     this.completions = new Completions3(this);
 | |
|     this.chat = new Chat(this);
 | |
|     this.embeddings = new Embeddings(this);
 | |
|     this.files = new Files2(this);
 | |
|     this.images = new Images(this);
 | |
|     this.audio = new Audio(this);
 | |
|     this.moderations = new Moderations(this);
 | |
|     this.models = new Models(this);
 | |
|     this.fineTuning = new FineTuning(this);
 | |
|     this.beta = new Beta(this);
 | |
|     this.batches = new Batches(this);
 | |
|     this._options = options;
 | |
|     this.apiKey = apiKey;
 | |
|     this.organization = organization;
 | |
|     this.project = project;
 | |
|   }
 | |
|   defaultQuery() {
 | |
|     return this._options.defaultQuery;
 | |
|   }
 | |
|   defaultHeaders(opts) {
 | |
|     return {
 | |
|       ...super.defaultHeaders(opts),
 | |
|       "OpenAI-Organization": this.organization,
 | |
|       "OpenAI-Project": this.project,
 | |
|       ...this._options.defaultHeaders
 | |
|     };
 | |
|   }
 | |
|   authHeaders(opts) {
 | |
|     return { Authorization: `Bearer ${this.apiKey}` };
 | |
|   }
 | |
| };
 | |
| _a = OpenAI;
 | |
| OpenAI.OpenAI = _a;
 | |
| OpenAI.OpenAIError = OpenAIError;
 | |
| OpenAI.APIError = APIError;
 | |
| OpenAI.APIConnectionError = APIConnectionError;
 | |
| OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError;
 | |
| OpenAI.APIUserAbortError = APIUserAbortError;
 | |
| OpenAI.NotFoundError = NotFoundError;
 | |
| OpenAI.ConflictError = ConflictError;
 | |
| OpenAI.RateLimitError = RateLimitError;
 | |
| OpenAI.BadRequestError = BadRequestError;
 | |
| OpenAI.AuthenticationError = AuthenticationError;
 | |
| OpenAI.InternalServerError = InternalServerError;
 | |
| OpenAI.PermissionDeniedError = PermissionDeniedError;
 | |
| OpenAI.UnprocessableEntityError = UnprocessableEntityError;
 | |
| OpenAI.toFile = toFile;
 | |
| OpenAI.fileFromPath = fileFromPath;
 | |
| var { OpenAIError: OpenAIError2, APIError: APIError2, APIConnectionError: APIConnectionError2, APIConnectionTimeoutError: APIConnectionTimeoutError2, APIUserAbortError: APIUserAbortError2, NotFoundError: NotFoundError2, ConflictError: ConflictError2, RateLimitError: RateLimitError2, BadRequestError: BadRequestError2, AuthenticationError: AuthenticationError2, InternalServerError: InternalServerError2, PermissionDeniedError: PermissionDeniedError2, UnprocessableEntityError: UnprocessableEntityError2 } = error_exports;
 | |
| (function(OpenAI2) {
 | |
|   OpenAI2.Page = Page;
 | |
|   OpenAI2.CursorPage = CursorPage;
 | |
|   OpenAI2.Completions = Completions3;
 | |
|   OpenAI2.Chat = Chat;
 | |
|   OpenAI2.Embeddings = Embeddings;
 | |
|   OpenAI2.Files = Files2;
 | |
|   OpenAI2.FileObjectsPage = FileObjectsPage;
 | |
|   OpenAI2.Images = Images;
 | |
|   OpenAI2.Audio = Audio;
 | |
|   OpenAI2.Moderations = Moderations;
 | |
|   OpenAI2.Models = Models;
 | |
|   OpenAI2.ModelsPage = ModelsPage;
 | |
|   OpenAI2.FineTuning = FineTuning;
 | |
|   OpenAI2.Beta = Beta;
 | |
|   OpenAI2.Batches = Batches;
 | |
|   OpenAI2.BatchesPage = BatchesPage;
 | |
| })(OpenAI || (OpenAI = {}));
 | |
| 
 | |
| // src/services/TranscriptionService.ts
 | |
| function TimerNotice2(heading, initialMessage) {
 | |
|   let currentMessage = initialMessage;
 | |
|   const startTime = Date.now();
 | |
|   let stopTime;
 | |
|   const notice = new import_obsidian23.Notice(initialMessage, 0);
 | |
|   function formatMsg(message) {
 | |
|     return `${heading} (${getTime()}):
 | |
| 
 | |
| ${message}`;
 | |
|   }
 | |
|   function update2(message) {
 | |
|     currentMessage = message;
 | |
|     notice.setMessage(formatMsg(currentMessage));
 | |
|   }
 | |
|   const interval = setInterval(() => {
 | |
|     notice.setMessage(formatMsg(currentMessage));
 | |
|   }, 1e3);
 | |
|   function getTime() {
 | |
|     return formatTime2(stopTime ? stopTime - startTime : Date.now() - startTime);
 | |
|   }
 | |
|   return {
 | |
|     update: update2,
 | |
|     hide: () => notice.hide(),
 | |
|     stop: () => {
 | |
|       stopTime = Date.now();
 | |
|       clearInterval(interval);
 | |
|     }
 | |
|   };
 | |
| }
 | |
| function formatTime2(ms) {
 | |
|   const seconds = Math.floor(ms / 1e3);
 | |
|   const minutes = Math.floor(seconds / 60);
 | |
|   const hours = Math.floor(minutes / 60);
 | |
|   return `${hours.toString().padStart(2, "0")}:${(minutes % 60).toString().padStart(2, "0")}:${(seconds % 60).toString().padStart(2, "0")}`;
 | |
| }
 | |
| var TranscriptionService = class {
 | |
|   constructor(plugin2) {
 | |
|     this.MAX_RETRIES = 3;
 | |
|     this.isTranscribing = false;
 | |
|     this.plugin = plugin2;
 | |
|     this.client = new OpenAI({
 | |
|       apiKey: this.plugin.settings.openAIApiKey,
 | |
|       dangerouslyAllowBrowser: true
 | |
|     });
 | |
|   }
 | |
|   async transcribeCurrentEpisode() {
 | |
|     if (this.isTranscribing) {
 | |
|       new import_obsidian23.Notice("A transcription is already in progress.");
 | |
|       return;
 | |
|     }
 | |
|     const currentEpisode2 = this.plugin.api.podcast;
 | |
|     if (!currentEpisode2) {
 | |
|       new import_obsidian23.Notice("No episode is currently playing.");
 | |
|       return;
 | |
|     }
 | |
|     const transcriptPath = FilePathTemplateEngine(this.plugin.settings.transcript.path, currentEpisode2);
 | |
|     const existingFile = this.plugin.app.vault.getAbstractFileByPath(transcriptPath);
 | |
|     if (existingFile instanceof import_obsidian23.TFile) {
 | |
|       new import_obsidian23.Notice(`You've already transcribed this episode - found ${transcriptPath}.`);
 | |
|       return;
 | |
|     }
 | |
|     this.isTranscribing = true;
 | |
|     const notice = TimerNotice2("Transcription", "Preparing to transcribe...");
 | |
|     try {
 | |
|       notice.update("Downloading episode...");
 | |
|       const downloadPath = await downloadEpisode(currentEpisode2, this.plugin.settings.download.path);
 | |
|       const podcastFile = this.plugin.app.vault.getAbstractFileByPath(downloadPath);
 | |
|       if (!podcastFile || !(podcastFile instanceof import_obsidian23.TFile)) {
 | |
|         throw new Error("Failed to download or locate the episode.");
 | |
|       }
 | |
|       notice.update("Preparing audio for transcription...");
 | |
|       const fileBuffer = await this.plugin.app.vault.readBinary(podcastFile);
 | |
|       const fileExtension = podcastFile.extension;
 | |
|       const mimeType = this.getMimeType(fileExtension);
 | |
|       const chunks = this.chunkFile(fileBuffer);
 | |
|       const files = this.createChunkFiles(chunks, podcastFile.basename, fileExtension, mimeType);
 | |
|       notice.update("Starting transcription...");
 | |
|       const transcription = await this.transcribeChunks(files, notice.update);
 | |
|       notice.update("Saving transcription...");
 | |
|       await this.saveTranscription(currentEpisode2, transcription);
 | |
|       notice.stop();
 | |
|       notice.update("Transcription completed and saved.");
 | |
|     } catch (error) {
 | |
|       console.error("Transcription error:", error);
 | |
|       notice.update(`Transcription failed: ${error.message}`);
 | |
|     } finally {
 | |
|       this.isTranscribing = false;
 | |
|       setTimeout(() => notice.hide(), 5e3);
 | |
|     }
 | |
|   }
 | |
|   chunkFile(fileBuffer) {
 | |
|     const CHUNK_SIZE_MB = 20;
 | |
|     const chunkSizeBytes = CHUNK_SIZE_MB * 1024 * 1024;
 | |
|     const chunks = [];
 | |
|     for (let i = 0; i < fileBuffer.byteLength; i += chunkSizeBytes) {
 | |
|       chunks.push(fileBuffer.slice(i, i + chunkSizeBytes));
 | |
|     }
 | |
|     return chunks;
 | |
|   }
 | |
|   createChunkFiles(chunks, fileName, fileExtension, mimeType) {
 | |
|     return chunks.map((chunk, index) => new File([chunk], `${fileName}.part${index}.${fileExtension}`, {
 | |
|       type: mimeType
 | |
|     }));
 | |
|   }
 | |
|   getMimeType(fileExtension) {
 | |
|     switch (fileExtension.toLowerCase()) {
 | |
|       case "mp3":
 | |
|         return "audio/mp3";
 | |
|       case "m4a":
 | |
|         return "audio/mp4";
 | |
|       case "ogg":
 | |
|         return "audio/ogg";
 | |
|       case "wav":
 | |
|         return "audio/wav";
 | |
|       case "flac":
 | |
|         return "audio/flac";
 | |
|       default:
 | |
|         return "audio/mpeg";
 | |
|     }
 | |
|   }
 | |
|   async transcribeChunks(files, updateNotice) {
 | |
|     const transcriptions = new Array(files.length);
 | |
|     let completedChunks = 0;
 | |
|     const updateProgress = () => {
 | |
|       const progress = (completedChunks / files.length * 100).toFixed(1);
 | |
|       updateNotice(`Transcribing... ${completedChunks}/${files.length} chunks completed (${progress}%)`);
 | |
|     };
 | |
|     updateProgress();
 | |
|     await Promise.all(files.map(async (file, index) => {
 | |
|       let retries = 0;
 | |
|       while (retries < this.MAX_RETRIES) {
 | |
|         try {
 | |
|           const result = await this.client.audio.transcriptions.create({
 | |
|             model: "whisper-1",
 | |
|             file
 | |
|           });
 | |
|           transcriptions[index] = result.text;
 | |
|           completedChunks++;
 | |
|           updateProgress();
 | |
|           break;
 | |
|         } catch (error) {
 | |
|           retries++;
 | |
|           if (retries >= this.MAX_RETRIES) {
 | |
|             console.error(`Failed to transcribe chunk ${index} after ${this.MAX_RETRIES} attempts:`, error);
 | |
|             transcriptions[index] = `[Error transcribing chunk ${index}]`;
 | |
|             completedChunks++;
 | |
|             updateProgress();
 | |
|           } else {
 | |
|             await new Promise((resolve) => setTimeout(resolve, 1e3 * retries));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }));
 | |
|     return transcriptions.join(" ");
 | |
|   }
 | |
|   async saveTranscription(episode, transcription) {
 | |
|     const transcriptPath = FilePathTemplateEngine(this.plugin.settings.transcript.path, episode);
 | |
|     const formattedTranscription = transcription.replace(/\.\s+/g, ".\n\n");
 | |
|     const transcriptContent = TranscriptTemplateEngine(this.plugin.settings.transcript.template, episode, formattedTranscription);
 | |
|     const vault = this.plugin.app.vault;
 | |
|     const directory = transcriptPath.substring(0, transcriptPath.lastIndexOf("/"));
 | |
|     if (directory && !vault.getAbstractFileByPath(directory)) {
 | |
|       await vault.createFolder(directory);
 | |
|     }
 | |
|     const file = vault.getAbstractFileByPath(transcriptPath);
 | |
|     if (!file) {
 | |
|       const newFile = await vault.create(transcriptPath, transcriptContent);
 | |
|       await this.plugin.app.workspace.getLeaf().openFile(newFile);
 | |
|     } else {
 | |
|       throw new Error("Expected a file but got a folder");
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/main.ts
 | |
| var PodNotes = class extends import_obsidian24.Plugin {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.maxLayoutReadyAttempts = 10;
 | |
|     this.layoutReadyAttempts = 0;
 | |
|   }
 | |
|   async onload() {
 | |
|     plugin.set(this);
 | |
|     await this.loadSettings();
 | |
|     playedEpisodes.set(this.settings.playedEpisodes);
 | |
|     savedFeeds.set(this.settings.savedFeeds);
 | |
|     playlists.set(this.settings.playlists);
 | |
|     queue.set(this.settings.queue);
 | |
|     favorites.set(this.settings.favorites);
 | |
|     localFiles.set(this.settings.localFiles);
 | |
|     downloadedEpisodes.set(this.settings.downloadedEpisodes);
 | |
|     if (this.settings.currentEpisode) {
 | |
|       currentEpisode.set(this.settings.currentEpisode);
 | |
|     }
 | |
|     this.playedEpisodeController = new EpisodeStatusController(playedEpisodes, this).on();
 | |
|     this.savedFeedsController = new SavedFeedsController(savedFeeds, this).on();
 | |
|     this.playlistController = new PlaylistController(playlists, this).on();
 | |
|     this.queueController = new QueueController(queue, this).on();
 | |
|     this.favoritesController = new FavoritesController(favorites, this).on();
 | |
|     this.localFilesController = new LocalFilesController(localFiles, this).on();
 | |
|     this.downloadedEpisodesController = new DownloadedEpisodesController(downloadedEpisodes, this).on();
 | |
|     this.currentEpisodeController = new CurrentEpisodeController(currentEpisode, this).on();
 | |
|     this.transcriptionService = new TranscriptionService(this);
 | |
|     this.api = new API();
 | |
|     this.addCommand({
 | |
|       id: "podnotes-show-leaf",
 | |
|       name: "Show PodNotes",
 | |
|       icon: "podcast",
 | |
|       checkCallback: function(checking) {
 | |
|         if (checking) {
 | |
|           return !this.app.workspace.getLeavesOfType(VIEW_TYPE).length;
 | |
|         }
 | |
|         this.app.workspace.getRightLeaf(false).setViewState({
 | |
|           type: VIEW_TYPE
 | |
|         });
 | |
|       }.bind(this)
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "start-playing",
 | |
|       name: "Play Podcast",
 | |
|       icon: "play-circle",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return !this.api.isPlaying && !!this.api.podcast;
 | |
|         }
 | |
|         this.api.start();
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "stop-playing",
 | |
|       name: "Stop Podcast",
 | |
|       icon: "stop-circle",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return this.api.isPlaying && !!this.api.podcast;
 | |
|         }
 | |
|         this.api.stop();
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "skip-backward",
 | |
|       name: "Skip Backward",
 | |
|       icon: "skip-back",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return this.api.isPlaying && !!this.api.podcast;
 | |
|         }
 | |
|         this.api.skipBackward();
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "skip-forward",
 | |
|       name: "Skip Forward",
 | |
|       icon: "skip-forward",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return this.api.isPlaying && !!this.api.podcast;
 | |
|         }
 | |
|         this.api.skipForward();
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "download-playing-episode",
 | |
|       name: "Download Playing Episode",
 | |
|       icon: "download",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return !!this.api.podcast;
 | |
|         }
 | |
|         const episode = this.api.podcast;
 | |
|         downloadEpisodeWithNotice(episode, this.settings.download.path);
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "hrpn",
 | |
|       name: "Reload PodNotes",
 | |
|       callback: () => {
 | |
|         const id = this.manifest.id;
 | |
|         this.app.plugins.disablePlugin(id).then(() => this.app.plugins.enablePlugin(id));
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "capture-timestamp",
 | |
|       name: "Capture Timestamp",
 | |
|       icon: "clock",
 | |
|       editorCheckCallback: (checking, editor, view) => {
 | |
|         if (checking) {
 | |
|           return !!this.api.podcast && !!this.settings.timestamp.template;
 | |
|         }
 | |
|         const cursorPos = editor.getCursor();
 | |
|         const capture = TimestampTemplateEngine(this.settings.timestamp.template);
 | |
|         editor.replaceRange(capture, cursorPos);
 | |
|         editor.setCursor(cursorPos.line, cursorPos.ch + capture.length);
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "create-podcast-note",
 | |
|       name: "Create Podcast Note",
 | |
|       icon: "file-plus",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return !!this.api.podcast && !!this.settings.note.path && !!this.settings.note.template;
 | |
|         }
 | |
|         createPodcastNote(this.api.podcast);
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "get-share-link-episode",
 | |
|       name: "Copy universal episode link to clipboard",
 | |
|       icon: "share",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return !!this.api.podcast;
 | |
|         }
 | |
|         getUniversalPodcastLink(this.api);
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "podnotes-toggle-playback",
 | |
|       name: "Toggle playback",
 | |
|       icon: "play",
 | |
|       checkCallback: (checking) => {
 | |
|         if (checking) {
 | |
|           return !!this.api.podcast;
 | |
|         }
 | |
|         this.api.togglePlayback();
 | |
|       }
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "podnotes-transcribe",
 | |
|       name: "Transcribe current episode",
 | |
|       callback: () => this.transcriptionService.transcribeCurrentEpisode()
 | |
|     });
 | |
|     this.addSettingTab(new PodNotesSettingsTab(this.app, this));
 | |
|     this.registerView(VIEW_TYPE, (leaf) => {
 | |
|       this.view = new MainView(leaf, this);
 | |
|       return this.view;
 | |
|     });
 | |
|     this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this));
 | |
|     this.registerObsidianProtocolHandler("podnotes", (action) => podNotesURIHandler(action, this.api));
 | |
|     this.registerEvent(getContextMenuHandler());
 | |
|   }
 | |
|   onLayoutReady() {
 | |
|     if (!this.app.workspace || !this.app.workspace.layoutReady) {
 | |
|       this.layoutReadyAttempts++;
 | |
|       if (this.layoutReadyAttempts < this.maxLayoutReadyAttempts) {
 | |
|         setTimeout(() => this.onLayoutReady(), 100);
 | |
|       } else {
 | |
|         console.error("Failed to initialize PodNotes layout after maximum attempts");
 | |
|       }
 | |
|       return;
 | |
|     }
 | |
|     if (this.app.workspace.getLeavesOfType(VIEW_TYPE).length) {
 | |
|       return;
 | |
|     }
 | |
|     const leaf = this.app.workspace.getRightLeaf(false);
 | |
|     if (leaf) {
 | |
|       leaf.setViewState({
 | |
|         type: VIEW_TYPE
 | |
|       });
 | |
|     }
 | |
|   }
 | |
|   onunload() {
 | |
|     this?.playedEpisodeController.off();
 | |
|     this?.savedFeedsController.off();
 | |
|     this?.playlistController.off();
 | |
|     this?.queueController.off();
 | |
|     this?.favoritesController.off();
 | |
|     this?.localFilesController.off();
 | |
|     this?.downloadedEpisodesController.off();
 | |
|     this?.currentEpisodeController.off();
 | |
|   }
 | |
|   async loadSettings() {
 | |
|     this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
 | |
|   }
 | |
|   async saveSettings() {
 | |
|     await this.saveData(this.settings);
 | |
|   }
 | |
| };
 | |
| /*! *****************************************************************************
 | |
| Copyright (c) Microsoft Corporation.
 | |
| 
 | |
| Permission to use, copy, modify, and/or distribute this software for any
 | |
| purpose with or without fee is hereby granted.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | |
| REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 | |
| AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | |
| INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | |
| LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | |
| OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
| PERFORMANCE OF THIS SOFTWARE.
 | |
| ***************************************************************************** */
 | |
| 
 | |
| /* nosourcemap */ |