@robinpath/google-forms
Advanced tools
| /** | ||
| * RobinPath Google Forms Module (Node port) | ||
| * | ||
| * Google Forms API v1 — create forms, fetch form definitions, list/get | ||
| * responses, mutate form structure via batchUpdate (add/update/delete items, | ||
| * sections, convert to quiz, etc.). Modeled on the gmail node module — shares | ||
| * the dual-auth contract, error taxonomy, and structured error envelopes. | ||
| * | ||
| * Authentication (two modes): | ||
| * | ||
| * 1. `access_token` (default, easiest — delegated user auth) — the user | ||
| * pastes a short-lived OAuth2 access token. If the credential also | ||
| * carries `refresh_token` + `client_id` + `client_secret`, expired | ||
| * tokens are refreshed automatically and written back to the vault. | ||
| * | ||
| * 2. `service_account` — Google Workspace Domain-Wide Delegation. Uses | ||
| * the service-account JSON key to mint a JWT-bearer assertion and | ||
| * impersonate `impersonated_user`. That user must have access to the | ||
| * target form (or be able to create one in their Drive). | ||
| * | ||
| * Credential type declared by this module: | ||
| * - google_forms : { auth_mode, access_token?, refresh_token?, client_id?, | ||
| * client_secret?, impersonated_user?, client_email?, | ||
| * private_key?, scopes? } | ||
| * | ||
| * API reference: https://developers.google.com/forms/api/reference/rest | ||
| */ | ||
| import type { BuiltinHandler, CredentialTypeSchema, FunctionMetadata, ModuleHost, ModuleMetadata } from "@robinpath/core"; | ||
| export declare function configureGoogleForms(h: ModuleHost): void; | ||
| export declare const GoogleFormsFunctions: Record<string, BuiltinHandler>; | ||
| export declare const GoogleFormsCredentialTypes: CredentialTypeSchema[]; | ||
| export declare const GoogleFormsFunctionMetadata: Record<string, FunctionMetadata>; | ||
| export declare const GoogleFormsModuleMetadata: ModuleMetadata; | ||
| //# sourceMappingURL=google-forms.d.ts.map |
| {"version":3,"file":"google-forms.d.ts","sourceRoot":"","sources":["../src/google-forms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAezB,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAExD;AAozBD,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAa/D,CAAC;AAIF,eAAO,MAAM,0BAA0B,EAAE,oBAAoB,EA2F5D,CAAC;AAuDF,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA6axE,CAAC;AAIF,eAAO,MAAM,yBAAyB,EAAE,cAkCvC,CAAC"} |
+1187
| /** | ||
| * RobinPath Google Forms Module (Node port) | ||
| * | ||
| * Google Forms API v1 — create forms, fetch form definitions, list/get | ||
| * responses, mutate form structure via batchUpdate (add/update/delete items, | ||
| * sections, convert to quiz, etc.). Modeled on the gmail node module — shares | ||
| * the dual-auth contract, error taxonomy, and structured error envelopes. | ||
| * | ||
| * Authentication (two modes): | ||
| * | ||
| * 1. `access_token` (default, easiest — delegated user auth) — the user | ||
| * pastes a short-lived OAuth2 access token. If the credential also | ||
| * carries `refresh_token` + `client_id` + `client_secret`, expired | ||
| * tokens are refreshed automatically and written back to the vault. | ||
| * | ||
| * 2. `service_account` — Google Workspace Domain-Wide Delegation. Uses | ||
| * the service-account JSON key to mint a JWT-bearer assertion and | ||
| * impersonate `impersonated_user`. That user must have access to the | ||
| * target form (or be able to create one in their Drive). | ||
| * | ||
| * Credential type declared by this module: | ||
| * - google_forms : { auth_mode, access_token?, refresh_token?, client_id?, | ||
| * client_secret?, impersonated_user?, client_email?, | ||
| * private_key?, scopes? } | ||
| * | ||
| * API reference: https://developers.google.com/forms/api/reference/rest | ||
| */ | ||
| import { createSign } from "node:crypto"; | ||
| import { Buffer } from "node:buffer"; | ||
| // ── Module-local state (populated by configure hook) ──────────────────── | ||
| const state = {}; | ||
| function host() { | ||
| if (!state.host) { | ||
| throw new Error("Google Forms module not initialized. Pass the adapter to rp.registerModule() via loadModule so its configure() hook runs first."); | ||
| } | ||
| return state.host; | ||
| } | ||
| export function configureGoogleForms(h) { | ||
| state.host = h; | ||
| } | ||
| // ── Constants ────────────────────────────────────────────────────────── | ||
| const TOKEN_URL = "https://oauth2.googleapis.com/token"; | ||
| const FORMS_API = "https://forms.googleapis.com/v1/"; | ||
| const DEFAULT_SCOPE = "https://www.googleapis.com/auth/forms.body https://www.googleapis.com/auth/forms.responses.readonly"; | ||
| const CREDENTIAL_TYPE = "google_forms"; | ||
| const tokenCache = new Map(); | ||
| const TOKEN_TTL_MS = 50 * 60 * 1000; | ||
| function cacheGet(key) { | ||
| const entry = tokenCache.get(key); | ||
| if (!entry) | ||
| return null; | ||
| if (entry.expiresAt <= Date.now()) { | ||
| tokenCache.delete(key); | ||
| return null; | ||
| } | ||
| return entry.token; | ||
| } | ||
| function cacheSet(key, token) { | ||
| tokenCache.set(key, { token, expiresAt: Date.now() + TOKEN_TTL_MS }); | ||
| } | ||
| function cacheDelete(key) { | ||
| tokenCache.delete(key); | ||
| } | ||
| function errorReturn(error, code, extra = {}) { | ||
| return { error, code, ...extra }; | ||
| } | ||
| function isErrorReturn(v) { | ||
| return !!v && typeof v === "object" && "error" in v && "code" in v; | ||
| } | ||
| async function resolveCredential(credentialSlug) { | ||
| if (!credentialSlug) { | ||
| return errorReturn("Credential slug is required.", "credential_not_found"); | ||
| } | ||
| let fields; | ||
| try { | ||
| fields = await host().credentials.get(credentialSlug); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "credential_not_found"); | ||
| } | ||
| if (!fields) { | ||
| return errorReturn(`Credential '${credentialSlug}' not found.`, "credential_not_found"); | ||
| } | ||
| const mode = String(fields.auth_mode ?? "access_token"); | ||
| if (mode === "service_account") { | ||
| return resolveServiceAccountToken(credentialSlug, fields); | ||
| } | ||
| return resolveAccessToken(credentialSlug, fields); | ||
| } | ||
| async function resolveAccessToken(credentialSlug, fields) { | ||
| const token = String(fields.access_token ?? ""); | ||
| const refreshToken = String(fields.refresh_token ?? ""); | ||
| const clientId = String(fields.client_id ?? ""); | ||
| const clientSecret = String(fields.client_secret ?? ""); | ||
| const refreshCacheKey = refreshToken && clientId && clientSecret | ||
| ? `refresh|${credentialSlug}|${refreshToken}` | ||
| : undefined; | ||
| if (refreshCacheKey) { | ||
| const cached = cacheGet(refreshCacheKey); | ||
| if (cached) { | ||
| return { | ||
| token: cached, | ||
| refreshCacheKey, | ||
| credentialSlug, | ||
| fields, | ||
| mode: "access_token", | ||
| }; | ||
| } | ||
| } | ||
| if (token) { | ||
| return { | ||
| token, | ||
| refreshCacheKey, | ||
| credentialSlug, | ||
| fields, | ||
| mode: "access_token", | ||
| }; | ||
| } | ||
| if (!refreshToken || !clientId || !clientSecret) { | ||
| return errorReturn("Credential has no `access_token`, and not enough info to refresh (need refresh_token + client_id + client_secret).", "token_missing"); | ||
| } | ||
| const refreshed = await refreshAccessToken(credentialSlug, refreshToken, clientId, clientSecret); | ||
| if (isErrorReturn(refreshed)) | ||
| return refreshed; | ||
| await writeBackAccessToken(credentialSlug, fields, refreshed.token); | ||
| return { | ||
| token: refreshed.token, | ||
| refreshCacheKey, | ||
| credentialSlug, | ||
| fields: { ...fields, access_token: refreshed.token }, | ||
| mode: "access_token", | ||
| }; | ||
| } | ||
| async function refreshAccessToken(credentialSlug, refreshToken, clientId, clientSecret) { | ||
| const body = new URLSearchParams({ | ||
| grant_type: "refresh_token", | ||
| refresh_token: refreshToken, | ||
| client_id: clientId, | ||
| client_secret: clientSecret, | ||
| }).toString(); | ||
| let response; | ||
| try { | ||
| response = await fetch(TOKEN_URL, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | ||
| body, | ||
| }); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "transport"); | ||
| } | ||
| const raw = await response.text(); | ||
| let decoded = {}; | ||
| try { | ||
| decoded = raw ? JSON.parse(raw) : {}; | ||
| } | ||
| catch { | ||
| decoded = {}; | ||
| } | ||
| const status = response.status; | ||
| const accessToken = String(decoded.access_token ?? ""); | ||
| if (status < 200 || status >= 300 || !accessToken) { | ||
| const msg = String(decoded.error_description ?? decoded.error ?? "Refresh failed."); | ||
| return errorReturn(msg, "token_exchange_failed", { status }); | ||
| } | ||
| cacheSet(`refresh|${credentialSlug}|${refreshToken}`, accessToken); | ||
| return { token: accessToken }; | ||
| } | ||
| async function writeBackAccessToken(slug, fields, newToken) { | ||
| try { | ||
| await host().credentials.set(slug, CREDENTIAL_TYPE, { | ||
| ...fields, | ||
| access_token: newToken, | ||
| }); | ||
| } | ||
| catch { | ||
| // Best-effort. | ||
| } | ||
| } | ||
| async function resolveServiceAccountToken(credentialSlug, fields) { | ||
| const email = String(fields.client_email ?? ""); | ||
| const key = String(fields.private_key ?? ""); | ||
| const scope = String(fields.scopes ?? DEFAULT_SCOPE); | ||
| const sub = String(fields.impersonated_user ?? ""); | ||
| if (!email || !key) { | ||
| return errorReturn("Service-account credential missing `client_email` or `private_key`.", "private_key_missing"); | ||
| } | ||
| if (!sub) { | ||
| return errorReturn("`impersonated_user` is required for service-account mode (Workspace user whose forms to access).", "token_missing"); | ||
| } | ||
| const cacheKey = `sa|${email}|${sub}|${scope}`; | ||
| const cached = cacheGet(cacheKey); | ||
| if (cached) { | ||
| return { | ||
| token: cached, | ||
| credentialSlug, | ||
| fields, | ||
| mode: "service_account", | ||
| }; | ||
| } | ||
| const jwt = buildJwt(email, key, scope, sub); | ||
| if (isErrorReturn(jwt)) | ||
| return jwt; | ||
| const body = new URLSearchParams({ | ||
| grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", | ||
| assertion: jwt, | ||
| }).toString(); | ||
| let response; | ||
| try { | ||
| response = await fetch(TOKEN_URL, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | ||
| body, | ||
| }); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "transport"); | ||
| } | ||
| const raw = await response.text(); | ||
| let decoded = {}; | ||
| try { | ||
| decoded = raw ? JSON.parse(raw) : {}; | ||
| } | ||
| catch { | ||
| decoded = {}; | ||
| } | ||
| const status = response.status; | ||
| const accessToken = String(decoded.access_token ?? ""); | ||
| if (status < 200 || status >= 300 || !accessToken) { | ||
| const msg = String(decoded.error_description ?? decoded.error ?? "Token exchange failed."); | ||
| return errorReturn(msg, "token_exchange_failed", { status }); | ||
| } | ||
| cacheSet(cacheKey, accessToken); | ||
| return { | ||
| token: accessToken, | ||
| credentialSlug, | ||
| fields, | ||
| mode: "service_account", | ||
| }; | ||
| } | ||
| function buildJwt(email, privateKey, scope, subject) { | ||
| const now = Math.floor(Date.now() / 1000); | ||
| const header = { alg: "RS256", typ: "JWT" }; | ||
| const payload = { | ||
| iss: email, | ||
| sub: subject, | ||
| scope, | ||
| aud: TOKEN_URL, | ||
| exp: now + 3600, | ||
| iat: now, | ||
| }; | ||
| const h = b64url(Buffer.from(JSON.stringify(header), "utf8")); | ||
| const p = b64url(Buffer.from(JSON.stringify(payload), "utf8")); | ||
| const signingInput = `${h}.${p}`; | ||
| try { | ||
| const signer = createSign("RSA-SHA256"); | ||
| signer.update(signingInput); | ||
| signer.end(); | ||
| const signature = signer.sign(privateKey); | ||
| return `${signingInput}.${b64url(signature)}`; | ||
| } | ||
| catch (e) { | ||
| return errorReturn(`Could not sign JWT: ${e instanceof Error ? e.message : String(e)}`, "jwt_sign_failed"); | ||
| } | ||
| } | ||
| function b64url(data) { | ||
| const buf = typeof data === "string" ? Buffer.from(data, "utf8") : data; | ||
| return buf | ||
| .toString("base64") | ||
| .replace(/\+/g, "-") | ||
| .replace(/\//g, "_") | ||
| .replace(/=+$/g, ""); | ||
| } | ||
| // ── HTTP — Forms API ─────────────────────────────────────────────────── | ||
| async function call(cred, method, path, body) { | ||
| const resolved = await resolveCredential(cred); | ||
| if (isErrorReturn(resolved)) | ||
| return resolved; | ||
| const first = await callWithToken(resolved, method, path, body); | ||
| if (isErrorReturn(first) && | ||
| first.status === 401 && | ||
| resolved.mode === "access_token") { | ||
| const refreshToken = String(resolved.fields.refresh_token ?? ""); | ||
| const clientId = String(resolved.fields.client_id ?? ""); | ||
| const clientSecret = String(resolved.fields.client_secret ?? ""); | ||
| if (refreshToken && clientId && clientSecret) { | ||
| if (resolved.refreshCacheKey) | ||
| cacheDelete(resolved.refreshCacheKey); | ||
| const refreshed = await refreshAccessToken(resolved.credentialSlug, refreshToken, clientId, clientSecret); | ||
| if (!isErrorReturn(refreshed)) { | ||
| await writeBackAccessToken(resolved.credentialSlug, resolved.fields, refreshed.token); | ||
| return callWithToken({ | ||
| ...resolved, | ||
| token: refreshed.token, | ||
| fields: { ...resolved.fields, access_token: refreshed.token }, | ||
| }, method, path, body); | ||
| } | ||
| } | ||
| } | ||
| return first; | ||
| } | ||
| async function callWithToken(resolved, method, path, body) { | ||
| const url = FORMS_API + path.replace(/^\/+/, ""); | ||
| const init = { | ||
| method, | ||
| headers: { | ||
| Authorization: `Bearer ${resolved.token}`, | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| }, | ||
| }; | ||
| if (body !== null && body !== undefined) { | ||
| init.body = JSON.stringify(body); | ||
| } | ||
| let response; | ||
| try { | ||
| response = await fetch(url, init); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "transport"); | ||
| } | ||
| const status = response.status; | ||
| const rawBody = await response.text(); | ||
| let decoded; | ||
| try { | ||
| decoded = rawBody ? JSON.parse(rawBody) : null; | ||
| } | ||
| catch { | ||
| decoded = { raw: rawBody }; | ||
| } | ||
| if (status >= 200 && status < 300) { | ||
| if (rawBody === "") | ||
| return { ok: true, status }; | ||
| if (decoded && typeof decoded === "object") | ||
| return decoded; | ||
| return { raw: rawBody }; | ||
| } | ||
| const errObj = decoded && typeof decoded === "object" && "error" in decoded | ||
| ? decoded.error | ||
| : null; | ||
| let message = `Forms API returned HTTP ${status}.`; | ||
| if (errObj && typeof errObj === "object" && "message" in errObj) { | ||
| message = String(errObj.message); | ||
| } | ||
| else if (typeof errObj === "string") { | ||
| message = errObj; | ||
| } | ||
| let code = "forms_error"; | ||
| if (status === 429) | ||
| code = "rate_limited"; | ||
| else if (status === 404) | ||
| code = "not_found"; | ||
| else if (status === 401) | ||
| code = "token_missing"; | ||
| else if (status === 403) | ||
| code = "permission_denied"; | ||
| else if (status === 400) | ||
| code = "validation_failed"; | ||
| return errorReturn(message, code, { | ||
| status, | ||
| forms_error: decoded && typeof decoded === "object" ? decoded : { raw: rawBody }, | ||
| }); | ||
| } | ||
| function buildQuery(params) { | ||
| const qs = []; | ||
| for (const [k, v] of Object.entries(params)) { | ||
| if (v === null || v === undefined || v === "") | ||
| continue; | ||
| if (typeof v === "boolean") { | ||
| qs.push(`${encodeURIComponent(k)}=${v ? "true" : "false"}`); | ||
| } | ||
| else { | ||
| qs.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`); | ||
| } | ||
| } | ||
| return qs.length ? `?${qs.join("&")}` : ""; | ||
| } | ||
| // ── Handlers — Forms ─────────────────────────────────────────────────── | ||
| const getForm = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| return (await call(cred, "GET", "forms/" + encodeURIComponent(formId), null)); | ||
| }; | ||
| const getFormInfo = async (args) => { | ||
| // Alias of getForm — fetches the form definition. | ||
| return getForm(args); | ||
| }; | ||
| const createForm = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const fields = args[1] && typeof args[1] === "object" && !Array.isArray(args[1]) | ||
| ? args[1] | ||
| : {}; | ||
| // Graph expects `{ info: { title, documentTitle? } }` — accept a bare string | ||
| // `title` or the shaped `info` object for convenience. | ||
| let body; | ||
| if (fields.info && typeof fields.info === "object" && !Array.isArray(fields.info)) { | ||
| body = fields; | ||
| } | ||
| else { | ||
| const info = {}; | ||
| if (fields.title !== undefined) | ||
| info.title = String(fields.title); | ||
| if (fields.documentTitle !== undefined) | ||
| info.documentTitle = String(fields.documentTitle); | ||
| if (fields.description !== undefined) | ||
| info.description = String(fields.description); | ||
| if (Object.keys(info).length === 0) { | ||
| return errorReturn("`info.title` or top-level `title` is required.", "validation_failed"); | ||
| } | ||
| body = { info }; | ||
| } | ||
| return (await call(cred, "POST", "forms", body)); | ||
| }; | ||
| const updateForm = async (args) => { | ||
| // Updating form settings is done via forms.batchUpdate with an | ||
| // updateFormInfo / updateSettings request. We provide a convenience | ||
| // wrapper that lets the caller pass partial `info` / `settings` and shapes | ||
| // the batchUpdate envelope automatically. | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const fields = args[2] && typeof args[2] === "object" && !Array.isArray(args[2]) | ||
| ? args[2] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| if (Object.keys(fields).length === 0) { | ||
| return errorReturn("Update fields are required.", "validation_failed"); | ||
| } | ||
| const requests = []; | ||
| if (fields.info && typeof fields.info === "object") { | ||
| const infoMask = String(fields.infoUpdateMask ?? Object.keys(fields.info).join(",")); | ||
| requests.push({ | ||
| updateFormInfo: { | ||
| info: fields.info, | ||
| updateMask: infoMask, | ||
| }, | ||
| }); | ||
| } | ||
| if (fields.settings && typeof fields.settings === "object") { | ||
| const settingsMask = String(fields.settingsUpdateMask ?? Object.keys(fields.settings).join(",")); | ||
| requests.push({ | ||
| updateSettings: { | ||
| settings: fields.settings, | ||
| updateMask: settingsMask, | ||
| }, | ||
| }); | ||
| } | ||
| if (Array.isArray(fields.requests)) { | ||
| // Allow passthrough of fully-formed requests. | ||
| for (const r of fields.requests) { | ||
| if (r && typeof r === "object") | ||
| requests.push(r); | ||
| } | ||
| } | ||
| if (requests.length === 0) { | ||
| return errorReturn("Provide `info`, `settings`, or `requests[]` to update.", "validation_failed"); | ||
| } | ||
| const body = { requests }; | ||
| if (fields.includeFormInResponse !== undefined) { | ||
| body.includeFormInResponse = Boolean(fields.includeFormInResponse); | ||
| } | ||
| if (fields.writeControl) { | ||
| body.writeControl = fields.writeControl; | ||
| } | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| const batchUpdate = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const body = args[2] && typeof args[2] === "object" && !Array.isArray(args[2]) | ||
| ? args[2] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| if (!Array.isArray(body.requests) || body.requests.length === 0) { | ||
| return errorReturn("`requests` must be a non-empty array.", "validation_failed"); | ||
| } | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| const convertToQuiz = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| const body = { | ||
| requests: [ | ||
| { | ||
| updateSettings: { | ||
| settings: { quizSettings: { isQuiz: true } }, | ||
| updateMask: "quizSettings.isQuiz", | ||
| }, | ||
| }, | ||
| ], | ||
| includeFormInResponse: true, | ||
| }; | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| // ── Handlers — Items (questions / sections) ──────────────────────────── | ||
| const addQuestion = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const item = args[2] && typeof args[2] === "object" && !Array.isArray(args[2]) | ||
| ? args[2] | ||
| : {}; | ||
| const opts = args[3] && typeof args[3] === "object" && !Array.isArray(args[3]) | ||
| ? args[3] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| if (Object.keys(item).length === 0) { | ||
| return errorReturn("Item definition is required.", "validation_failed"); | ||
| } | ||
| const index = Number(opts.index ?? 0) | 0; | ||
| const body = { | ||
| requests: [ | ||
| { createItem: { item, location: { index } } }, | ||
| ], | ||
| }; | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| const updateQuestion = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const itemIndex = Number(args[2] ?? -1) | 0; | ||
| const item = args[3] && typeof args[3] === "object" && !Array.isArray(args[3]) | ||
| ? args[3] | ||
| : {}; | ||
| const opts = args[4] && typeof args[4] === "object" && !Array.isArray(args[4]) | ||
| ? args[4] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| if (itemIndex < 0) { | ||
| return errorReturn("itemIndex must be >= 0.", "validation_failed"); | ||
| } | ||
| const updateMask = String(opts.updateMask ?? "title,description,questionItem"); | ||
| const body = { | ||
| requests: [ | ||
| { | ||
| updateItem: { | ||
| item, | ||
| location: { index: itemIndex }, | ||
| updateMask, | ||
| }, | ||
| }, | ||
| ], | ||
| }; | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| const deleteQuestion = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const itemIndex = Number(args[2] ?? -1) | 0; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| if (itemIndex < 0) { | ||
| return errorReturn("itemIndex must be >= 0.", "validation_failed"); | ||
| } | ||
| const body = { | ||
| requests: [{ deleteItem: { location: { index: itemIndex } } }], | ||
| }; | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| const addSection = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const fields = args[2] && typeof args[2] === "object" && !Array.isArray(args[2]) | ||
| ? args[2] | ||
| : {}; | ||
| const opts = args[3] && typeof args[3] === "object" && !Array.isArray(args[3]) | ||
| ? args[3] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| const index = Number(opts.index ?? 0) | 0; | ||
| const item = { | ||
| pageBreakItem: {}, | ||
| }; | ||
| if (fields.title !== undefined) | ||
| item.title = String(fields.title); | ||
| if (fields.description !== undefined) | ||
| item.description = String(fields.description); | ||
| const body = { | ||
| requests: [{ createItem: { item, location: { index } } }], | ||
| }; | ||
| return (await call(cred, "POST", "forms/" + encodeURIComponent(formId) + ":batchUpdate", body)); | ||
| }; | ||
| // ── Handlers — Responses ─────────────────────────────────────────────── | ||
| const listResponses = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const opts = args[2] && typeof args[2] === "object" && !Array.isArray(args[2]) | ||
| ? args[2] | ||
| : {}; | ||
| if (!formId) { | ||
| return errorReturn("formId is required.", "validation_failed"); | ||
| } | ||
| const query = buildQuery({ | ||
| pageSize: opts.pageSize, | ||
| pageToken: opts.pageToken, | ||
| filter: opts.filter, | ||
| }); | ||
| return (await call(cred, "GET", "forms/" + encodeURIComponent(formId) + "/responses" + query, null)); | ||
| }; | ||
| const getResponse = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const formId = String(args[1] ?? ""); | ||
| const responseId = String(args[2] ?? ""); | ||
| if (!formId || !responseId) { | ||
| return errorReturn("formId and responseId are required.", "validation_failed"); | ||
| } | ||
| return (await call(cred, "GET", "forms/" + | ||
| encodeURIComponent(formId) + | ||
| "/responses/" + | ||
| encodeURIComponent(responseId), null)); | ||
| }; | ||
| // ── Exports: functions map ───────────────────────────────────────────── | ||
| export const GoogleFormsFunctions = { | ||
| getForm, | ||
| getFormInfo, | ||
| createForm, | ||
| updateForm, | ||
| batchUpdate, | ||
| convertToQuiz, | ||
| addQuestion, | ||
| updateQuestion, | ||
| deleteQuestion, | ||
| addSection, | ||
| listResponses, | ||
| getResponse, | ||
| }; | ||
| // ── Exports: credential types ────────────────────────────────────────── | ||
| export const GoogleFormsCredentialTypes = [ | ||
| { | ||
| slug: CREDENTIAL_TYPE, | ||
| title: "Google Forms", | ||
| icon: "clipboard-list", | ||
| fields: [ | ||
| { | ||
| name: "auth_mode", | ||
| title: "Authentication mode", | ||
| type: "text", | ||
| required: true, | ||
| placeholder: "access_token", | ||
| description: "Choose how this credential authenticates:\n • access_token — Paste an OAuth2 access token obtained externally.\n • service_account — Google Workspace Domain-Wide Delegation impersonating a user.", | ||
| }, | ||
| { | ||
| name: "access_token", | ||
| title: "Access token", | ||
| type: "password", | ||
| required: false, | ||
| placeholder: "ya29.a0Af…", | ||
| description: "OAuth2 access token for the Forms API. Required when auth_mode = access_token. Tokens expire after ~1 hour — supply refresh_token + client_id + client_secret below for automatic refresh. Obtain one at https://developers.google.com/oauthplayground (scopes `forms.body` for editing and `forms.responses.readonly` to read responses).", | ||
| }, | ||
| { | ||
| name: "refresh_token", | ||
| title: "Refresh token", | ||
| type: "password", | ||
| required: false, | ||
| placeholder: "1//0g…", | ||
| description: "Optional. When present with client_id + client_secret, the module will automatically exchange it for a fresh access_token when the current one expires. Refreshed tokens are cached for ~50 minutes and written back to the credential vault.", | ||
| }, | ||
| { | ||
| name: "client_id", | ||
| title: "OAuth client ID", | ||
| type: "text", | ||
| required: false, | ||
| placeholder: "123-abc.apps.googleusercontent.com", | ||
| description: "Optional. The OAuth 2.0 client ID from Google Cloud Console. Needed for the refresh-token flow.", | ||
| }, | ||
| { | ||
| name: "client_secret", | ||
| title: "OAuth client secret", | ||
| type: "password", | ||
| required: false, | ||
| placeholder: "GOCSPX-…", | ||
| description: "Optional. The OAuth 2.0 client secret from Google Cloud Console. Needed for the refresh-token flow.", | ||
| }, | ||
| { | ||
| name: "impersonated_user", | ||
| title: "Impersonated user (service account only)", | ||
| type: "text", | ||
| required: false, | ||
| placeholder: "user@yourcompany.com", | ||
| description: "Required when auth_mode = service_account. The Google Workspace user whose Forms this credential accesses. The service account must have Domain-Wide Delegation for the Forms scopes in the Workspace admin console.", | ||
| }, | ||
| { | ||
| name: "client_email", | ||
| title: "Service account email", | ||
| type: "text", | ||
| required: false, | ||
| placeholder: "name@project-id.iam.gserviceaccount.com", | ||
| description: "Required when auth_mode = service_account. The client_email field from your service-account JSON key.", | ||
| pattern: "@[a-z0-9-]+\\.iam\\.gserviceaccount\\.com$", | ||
| }, | ||
| { | ||
| name: "private_key", | ||
| title: "Service account private key (PEM)", | ||
| type: "textarea", | ||
| required: false, | ||
| placeholder: "-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----\n", | ||
| description: "Required when auth_mode = service_account. The private_key field from your service-account JSON. Paste it as-is, including the BEGIN/END lines.", | ||
| }, | ||
| { | ||
| name: "scopes", | ||
| title: "Scopes", | ||
| type: "text", | ||
| required: false, | ||
| placeholder: "https://www.googleapis.com/auth/forms.body https://www.googleapis.com/auth/forms.responses.readonly", | ||
| description: "Space-separated OAuth scopes. Defaults to `forms.body` + `forms.responses.readonly` (edit form structure + read responses).\n\nCommon alternatives:\n • forms.body.readonly — read form definition\n • forms.responses.readonly — read responses\n\nSee https://developers.google.com/forms/api/reference/rest#auth.", | ||
| }, | ||
| ], | ||
| }, | ||
| ]; | ||
| // ── Metadata: parameters + errors ────────────────────────────────────── | ||
| const credentialParam = { | ||
| name: "credential", | ||
| title: "Credential", | ||
| description: "Slug of a saved `google_forms` credential.", | ||
| dataType: "string", | ||
| formInputType: "resource", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "my_google_forms", | ||
| resource: { | ||
| type: "credential", | ||
| listFn: "credential.list", | ||
| modes: ["list", "expression"], | ||
| searchable: true, | ||
| filter: { type: CREDENTIAL_TYPE }, | ||
| }, | ||
| }; | ||
| const formIdParam = { | ||
| name: "formId", | ||
| title: "Form ID", | ||
| description: "Google Forms form ID — the long string in `docs.google.com/forms/d/{ID}/edit`. Returned by `createForm` on creation, otherwise copy from the URL.", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "1ABC...xyz", | ||
| }; | ||
| const commonErrors = { | ||
| credential_not_found: "No credential with that slug exists in the vault.", | ||
| token_missing: "Credential has no `access_token` (and no refresh_token for renewal).", | ||
| private_key_missing: "Service-account credential missing `client_email` or `private_key`.", | ||
| jwt_sign_failed: "Could not sign the JWT — `private_key` is malformed (must be PEM).", | ||
| token_exchange_failed: "Google rejected the token exchange — verify the credential values.", | ||
| transport: "Network failure calling Forms API.", | ||
| forms_error: "Forms API returned an error — see `forms_error.error`.", | ||
| permission_denied: "Access token lacks the required scope, or Domain-Wide Delegation is missing for the service account.", | ||
| rate_limited: "Forms API rate limit hit.", | ||
| not_found: "Requested form or response does not exist.", | ||
| validation_failed: "Request failed validation — see `forms_error`.", | ||
| }; | ||
| // ── Function metadata ────────────────────────────────────────────────── | ||
| export const GoogleFormsFunctionMetadata = { | ||
| getForm: { | ||
| title: "Get form", | ||
| summary: "Fetch a form's full definition", | ||
| description: "Calls `GET /v1/forms/{formId}`. Returns `{formId, info: {title,documentTitle,description}, settings, items: [...], revisionId, responderUri, linkedSheetId?, publishSettings}`.", | ||
| group: "forms", | ||
| action: "read", | ||
| icon: "clipboard-list", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "read"], | ||
| parameters: [credentialParam, formIdParam], | ||
| returnType: "object", | ||
| returnDescription: "Form resource.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.getForm "my_google_forms" "1ABC...xyz"', | ||
| }, | ||
| getFormInfo: { | ||
| title: "Get form info", | ||
| summary: "Alias of getForm", | ||
| description: "Alias of `getForm`. Kept for backwards compatibility. Calls `GET /v1/forms/{formId}`.", | ||
| group: "forms", | ||
| action: "read", | ||
| icon: "info", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "read"], | ||
| parameters: [credentialParam, formIdParam], | ||
| returnType: "object", | ||
| returnDescription: "Form resource (same as getForm).", | ||
| errors: commonErrors, | ||
| example: 'google-forms.getFormInfo "my_google_forms" "1ABC...xyz"', | ||
| }, | ||
| createForm: { | ||
| title: "Create form", | ||
| summary: "Create a new Google Form", | ||
| description: "Calls `POST /v1/forms`. Accepts either a bare `title` (shorthand) or a full `{info:{title, documentTitle?, description?}}` object. Forms cannot be created with items in one call — use `addQuestion` / `batchUpdate` after creation to populate them.", | ||
| group: "forms", | ||
| action: "create", | ||
| icon: "clipboard-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "create"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "fields", | ||
| title: "Fields", | ||
| description: "Recognized shapes:\n { title, documentTitle?, description? } — shorthand\n { info: { title, documentTitle?, description? } } — Graph-native", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 4, | ||
| placeholder: '{"title": "Customer feedback", "description": "Q3 2026"}', | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "Created Form resource including its `formId`.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.createForm "my_google_forms" {title:"Customer feedback"}', | ||
| }, | ||
| updateForm: { | ||
| title: "Update form", | ||
| summary: "Update form info / settings via batchUpdate shorthand", | ||
| description: "Shorthand wrapper around `forms:batchUpdate`. Pass partial `info` and/or `settings` objects; the module builds `updateFormInfo` / `updateSettings` requests with auto-derived `updateMask`s. For anything more complex, use `batchUpdate` directly.", | ||
| group: "forms", | ||
| action: "update", | ||
| icon: "pencil", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "update"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "fields", | ||
| title: "Fields", | ||
| description: "Recognized keys:\n info : {title?, description?, documentTitle?}\n infoUpdateMask : override auto-derived mask for `info`\n settings : Graph FormSettings resource (e.g. {quizSettings: {isQuiz: true}})\n settingsUpdateMask : override auto-derived mask for `settings`\n requests : array of raw batchUpdate requests appended after the above\n includeFormInResponse : bool\n writeControl : WriteControl resource", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 6, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response — { replies: [...], form?, writeControl? }", | ||
| errors: commonErrors, | ||
| example: 'google-forms.updateForm "my_google_forms" "1ABC..." {info:{title:"Renamed"}}', | ||
| }, | ||
| batchUpdate: { | ||
| title: "Batch update form", | ||
| summary: "Run any Forms API batchUpdate request list", | ||
| description: "Calls `POST /v1/forms/{formId}:batchUpdate`. The full power of the Forms API — create/update/delete items, move items, update settings, update form info. See https://developers.google.com/forms/api/reference/rest/v1/forms/batchUpdate.", | ||
| group: "forms", | ||
| action: "write", | ||
| icon: "list-checks", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "batch-update"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "body", | ||
| title: "BatchUpdate body", | ||
| description: "Full `batchUpdate` request envelope. Required keys:\n requests : array of Request resources\n includeFormInResponse? : bool\n writeControl? : WriteControl", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 8, | ||
| placeholder: '{\n "requests": [\n { "updateFormInfo": { "info": { "title": "New" }, "updateMask": "title" } }\n ]\n}', | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.batchUpdate "my_google_forms" "1ABC..." {requests:[{updateFormInfo:{info:{title:"New"},updateMask:"title"}}]}', | ||
| }, | ||
| convertToQuiz: { | ||
| title: "Convert form to quiz", | ||
| summary: "Toggle the form into Quiz mode", | ||
| description: "Shortcut for a `batchUpdate` that sets `settings.quizSettings.isQuiz = true`. After this, items can define point values and correct answers.", | ||
| group: "forms", | ||
| action: "update", | ||
| icon: "graduation-cap", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "quiz"], | ||
| parameters: [credentialParam, formIdParam], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response with `form` included.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.convertToQuiz "my_google_forms" "1ABC..."', | ||
| }, | ||
| addQuestion: { | ||
| title: "Add question", | ||
| summary: "Append or insert an Item (question) into the form", | ||
| description: "Shortcut for a `batchUpdate` with a single `createItem` request. Pass the full Item resource as `item`; use `options.index` to insert at a specific position (default 0 — very top).", | ||
| group: "items", | ||
| action: "create", | ||
| icon: "plus-circle", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "question", "item", "create"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "item", | ||
| title: "Item", | ||
| description: "Google Forms Item resource. Common shape:\n {\n title: \"What's your name?\",\n questionItem: {\n question: {\n required: true,\n textQuestion: { paragraph: false }\n }\n }\n }\nSee https://developers.google.com/forms/api/reference/rest/v1/forms#Item.", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 8, | ||
| placeholder: '{\n "title": "How satisfied are you?",\n "questionItem": {\n "question": {\n "required": true,\n "scaleQuestion": { "low": 1, "high": 5 }\n }\n }\n}', | ||
| }, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n index : 0-based insertion index (default 0 — insert at the top)", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 2, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.addQuestion "my_google_forms" "1ABC..." {title:"Name?",questionItem:{question:{textQuestion:{paragraph:false}}}}', | ||
| }, | ||
| updateQuestion: { | ||
| title: "Update question", | ||
| summary: "Patch an item at a given index", | ||
| description: "Shortcut for a `batchUpdate` with a single `updateItem` request. You supply the partial Item and an `updateMask` (default `title,description,questionItem`).", | ||
| group: "items", | ||
| action: "update", | ||
| icon: "pencil", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "question", "item", "update"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "itemIndex", | ||
| title: "Item index", | ||
| description: "0-based index of the item within the form's items array.", | ||
| dataType: "number", | ||
| formInputType: "number", | ||
| required: true, | ||
| allowExpression: true, | ||
| }, | ||
| { | ||
| name: "item", | ||
| title: "Partial Item", | ||
| description: "Only the fields listed in `options.updateMask` are applied.", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 6, | ||
| }, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n updateMask : comma-separated fields (default title,description,questionItem)", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 2, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.updateQuestion "my_google_forms" "1ABC..." 0 {title:"Renamed"} {updateMask:"title"}', | ||
| }, | ||
| deleteQuestion: { | ||
| title: "Delete question", | ||
| summary: "Remove the item at a given index", | ||
| description: "Shortcut for a `batchUpdate` with a single `deleteItem` request. Indices shift after deletion — delete high-to-low when removing multiple.", | ||
| group: "items", | ||
| action: "delete", | ||
| icon: "trash", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "question", "item", "delete"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "itemIndex", | ||
| title: "Item index", | ||
| description: "0-based index of the item to delete.", | ||
| dataType: "number", | ||
| formInputType: "number", | ||
| required: true, | ||
| allowExpression: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.deleteQuestion "my_google_forms" "1ABC..." 0', | ||
| }, | ||
| addSection: { | ||
| title: "Add section", | ||
| summary: "Insert a page-break item (section header) into the form", | ||
| description: "Shortcut for a `batchUpdate` that creates a `pageBreakItem`. Pass a `title` and optional `description`.", | ||
| group: "items", | ||
| action: "create", | ||
| icon: "layout", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["forms", "section", "page-break"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "fields", | ||
| title: "Section fields", | ||
| description: "Recognized keys:\n title : string\n description : string", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| placeholder: '{"title": "Section 2", "description": "About you"}', | ||
| }, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n index : 0-based insertion index (default 0)", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 2, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "BatchUpdate response.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.addSection "my_google_forms" "1ABC..." {title:"About you"}', | ||
| }, | ||
| listResponses: { | ||
| title: "List responses", | ||
| summary: "List form submissions", | ||
| description: "Calls `GET /v1/forms/{formId}/responses`. Returns response rows with per-question answers. Requires the `forms.responses.readonly` scope.", | ||
| group: "responses", | ||
| action: "query", | ||
| icon: "inbox", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "responses", "submissions"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n pageSize : 1-5000 (default 5000)\n pageToken : next-page token\n filter : Graph filter (e.g. `timestamp > 2026-04-01T00:00:00Z`)", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ responses: [FormResponse, …], nextPageToken? }", | ||
| errors: commonErrors, | ||
| example: 'google-forms.listResponses "my_google_forms" "1ABC..." {pageSize:100}', | ||
| }, | ||
| getResponse: { | ||
| title: "Get response", | ||
| summary: "Fetch a single response by ID", | ||
| description: "Calls `GET /v1/forms/{formId}/responses/{responseId}`.", | ||
| group: "responses", | ||
| action: "read", | ||
| icon: "mail-open", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["forms", "response", "read"], | ||
| parameters: [ | ||
| credentialParam, | ||
| formIdParam, | ||
| { | ||
| name: "responseId", | ||
| title: "Response ID", | ||
| description: "Response ID from `listResponses` — `ACYDBNh...` shape.", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "FormResponse resource.", | ||
| errors: commonErrors, | ||
| example: 'google-forms.getResponse "my_google_forms" "1ABC..." "ACYDBNh..."', | ||
| }, | ||
| }; | ||
| // ── Module metadata ──────────────────────────────────────────────────── | ||
| export const GoogleFormsModuleMetadata = { | ||
| slug: "google-forms", | ||
| title: "Google Forms", | ||
| summary: "Google Forms — create forms, add/update/delete questions and sections, convert to quiz, read responses", | ||
| description: 'Programmatic access to Google Forms (Forms API v1).\n\n**Authentication — two modes, same credential type (`google_forms`):**\n\n 1. `access_token` — Paste an OAuth2 token with `forms.body` + `forms.responses.readonly` scopes. Supply `refresh_token` + client ID/secret to auto-rotate.\n\n 2. `service_account` — Workspace Domain-Wide Delegation, impersonating the user whose forms the automation operates on.\n\n**Mutations go through `batchUpdate`** — the convenience helpers (`addQuestion`, `updateQuestion`, `deleteQuestion`, `addSection`, `updateForm`, `convertToQuiz`) just shape a one-request `batchUpdate` payload. For anything more complex, call `batchUpdate` directly.\n\nDocs: https://developers.google.com/forms/api/reference/rest', | ||
| category: "productivity", | ||
| icon: "icon.svg", | ||
| color: "#7248B9", | ||
| version: "0.2.0", | ||
| docsUrl: "https://docs.robinpath.com/modules/google-forms", | ||
| status: "stable", | ||
| requires: [], | ||
| minNodeVersion: "18.0.0", | ||
| credentialsType: CREDENTIAL_TYPE, | ||
| operationGroups: { | ||
| forms: { | ||
| title: "Forms", | ||
| description: "Create, read, and update forms.", | ||
| order: 1, | ||
| }, | ||
| items: { | ||
| title: "Items", | ||
| description: "Add, update, and delete questions and sections.", | ||
| order: 2, | ||
| }, | ||
| responses: { | ||
| title: "Responses", | ||
| description: "Read form submissions.", | ||
| order: 3, | ||
| }, | ||
| }, | ||
| methods: Object.keys(GoogleFormsFunctions), | ||
| }; | ||
| //# sourceMappingURL=google-forms.js.map |
| {"version":3,"file":"google-forms.js","sourceRoot":"","sources":["../src/google-forms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrC,2EAA2E;AAE3E,MAAM,KAAK,GAA0B,EAAE,CAAC;AAExC,SAAS,IAAI;IACX,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,iIAAiI,CAClI,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAa;IAChD,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;AACjB,CAAC;AAED,0EAA0E;AAE1E,MAAM,SAAS,GAAG,qCAAqC,CAAC;AACxD,MAAM,SAAS,GAAG,kCAAkC,CAAC;AACrD,MAAM,aAAa,GACjB,qGAAqG,CAAC;AACxG,MAAM,eAAe,GAAG,cAAc,CAAC;AAQvC,MAAM,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;AACtD,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpC,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAClC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,KAAa;IAC1C,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAWD,SAAS,WAAW,CAClB,KAAa,EACb,IAAY,EACZ,QAAiC,EAAE;IAEnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,EAAiB,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,CAAU;IAC/B,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,IAAI,MAAM,IAAK,CAAY,CAAC;AACjF,CAAC;AAYD,KAAK,UAAU,iBAAiB,CAC9B,cAAsB;IAEtB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC,8BAA8B,EAAE,sBAAsB,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,MAAsC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1C,sBAAsB,CACvB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAChB,eAAe,cAAc,cAAc,EAC3C,sBAAsB,CACvB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC,CAAC;IACxD,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,OAAO,0BAA0B,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,cAAsB,EACtB,MAA+B;IAE/B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,eAAe,GACnB,YAAY,IAAI,QAAQ,IAAI,YAAY;QACtC,CAAC,CAAC,WAAW,cAAc,IAAI,YAAY,EAAE;QAC7C,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;gBACL,KAAK,EAAE,MAAM;gBACb,eAAe;gBACf,cAAc;gBACd,MAAM;gBACN,IAAI,EAAE,cAAc;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,KAAK;YACL,eAAe;YACf,cAAc;YACd,MAAM;YACN,IAAI,EAAE,cAAc;SACrB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;QAChD,OAAO,WAAW,CAChB,oHAAoH,EACpH,eAAe,CAChB,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,kBAAkB,CACxC,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,YAAY,CACb,CAAC;IACF,IAAI,aAAa,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACpE,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,eAAe;QACf,cAAc;QACd,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,KAAK,EAAE;QACpD,IAAI,EAAE,cAAc;KACrB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,cAAsB,EACtB,YAAoB,EACpB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,UAAU,EAAE,eAAe;QAC3B,aAAa,EAAE,YAAY;QAC3B,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,YAAY;KAC5B,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEd,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1C,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,OAAO,GAA4B,EAAE,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,GAAG,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,CAChB,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,KAAK,IAAI,iBAAiB,CAChE,CAAC;QACF,OAAO,WAAW,CAAC,GAAG,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ,CAAC,WAAW,cAAc,IAAI,YAAY,EAAE,EAAE,WAAW,CAAC,CAAC;IACnE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,IAAY,EACZ,MAA+B,EAC/B,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE;YAClD,GAAG,MAAM;YACT,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,cAAsB,EACtB,MAA+B;IAE/B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAEnD,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QACnB,OAAO,WAAW,CAChB,qEAAqE,EACrE,qBAAqB,CACtB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,WAAW,CAChB,kGAAkG,EAClG,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,KAAK,EAAE,MAAM;YACb,cAAc;YACd,MAAM;YACN,IAAI,EAAE,iBAAiB;SACxB,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,aAAa,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAEnC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,UAAU,EAAE,6CAA6C;QACzD,SAAS,EAAE,GAAG;KACf,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEd,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1C,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,OAAO,GAA4B,EAAE,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,GAAG,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,CAChB,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,KAAK,IAAI,wBAAwB,CACvE,CAAC;QACF,OAAO,WAAW,CAAC,GAAG,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAChC,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,cAAc;QACd,MAAM;QACN,IAAI,EAAE,iBAAiB;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CACf,KAAa,EACb,UAAkB,EAClB,KAAa,EACb,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,OAAO;QACZ,KAAK;QACL,GAAG,EAAE,SAAS;QACd,GAAG,EAAE,GAAG,GAAG,IAAI;QACf,GAAG,EAAE,GAAG;KACT,CAAC;IACF,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IAChD,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,uBAAuB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EACnE,iBAAiB,CAClB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,IAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,OAAO,GAAG;SACP,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,0EAA0E;AAE1E,KAAK,UAAU,IAAI,CACjB,IAAY,EACZ,MAAc,EACd,IAAY,EACZ,IAAoB;IAEpB,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE7C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChE,IACE,aAAa,CAAC,KAAK,CAAC;QACpB,KAAK,CAAC,MAAM,KAAK,GAAG;QACpB,QAAQ,CAAC,IAAI,KAAK,cAAc,EAChC,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACjE,IAAI,YAAY,IAAI,QAAQ,IAAI,YAAY,EAAE,CAAC;YAC7C,IAAI,QAAQ,CAAC,eAAe;gBAAE,WAAW,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;YACpE,MAAM,SAAS,GAAG,MAAM,kBAAkB,CACxC,QAAQ,CAAC,cAAc,EACvB,YAAY,EACZ,QAAQ,EACR,YAAY,CACb,CAAC;YACF,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9B,MAAM,oBAAoB,CACxB,QAAQ,CAAC,cAAc,EACvB,QAAQ,CAAC,MAAM,EACf,SAAS,CAAC,KAAK,CAChB,CAAC;gBACF,OAAO,aAAa,CAClB;oBACE,GAAG,QAAQ;oBACX,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,MAAM,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,KAAK,EAAE;iBAC9D,EACD,MAAM,EACN,IAAI,EACJ,IAAI,CACL,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,QAAsB,EACtB,MAAc,EACd,IAAY,EACZ,IAAoB;IAEpB,MAAM,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,IAAI,GAAgB;QACxB,MAAM;QACN,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,QAAQ,CAAC,KAAK,EAAE;YACzC,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC3B;KACF,CAAC;IACF,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAC1C,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;QAClC,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAChD,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC;QAC3D,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GACV,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAK,OAAkB;QACtE,CAAC,CAAG,OAA8B,CAAC,KAAiB;QACpD,CAAC,CAAC,IAAI,CAAC;IACX,IAAI,OAAO,GAAG,2BAA2B,MAAM,GAAG,CAAC;IACnD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QAChE,OAAO,GAAG,MAAM,CAAE,MAA+B,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,GAAG,aAAa,CAAC;IACzB,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,cAAc,CAAC;SACrC,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,WAAW,CAAC;SACvC,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,eAAe,CAAC;SAC3C,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,mBAAmB,CAAC;SAC/C,IAAI,MAAM,KAAK,GAAG;QAAE,IAAI,GAAG,mBAAmB,CAAC;IAEpD,OAAO,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE;QAChC,MAAM;QACN,WAAW,EACT,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE;KACtE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,MAA+B;IACjD,MAAM,EAAE,GAAa,EAAE,CAAC;IACxB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;YAAE,SAAS;QACxD,IAAI,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3B,EAAE,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7C,CAAC;AAED,0EAA0E;AAE1E,MAAM,OAAO,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAQ,CAAC;AACvF,CAAC,CAAC;AAEF,MAAM,WAAW,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,kDAAkD;IAClD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GACV,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,6EAA6E;IAC7E,uDAAuD;IACvD,IAAI,IAA6B,CAAC;IAClC,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAClF,IAAI,GAAG,MAAiC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1F,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACpF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,WAAW,CAChB,gDAAgD,EAChD,mBAAmB,CACb,CAAC;QACX,CAAC;QACD,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAQ,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,UAAU,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IAChD,+DAA+D;IAC/D,oEAAoE;IACpE,2EAA2E;IAC3E,0CAA0C;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,MAAM,GACV,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,WAAW,CAChB,6BAA6B,EAC7B,mBAAmB,CACb,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAE/C,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CACrB,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5D,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC;YACZ,cAAc,EAAE;gBACd,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,UAAU,EAAE,QAAQ;aACrB;SACF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC3D,MAAM,YAAY,GAAG,MAAM,CACzB,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CACpE,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC;YACZ,cAAc,EAAE;gBACd,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,UAAU,EAAE,YAAY;aACzB;SACF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,8CAA8C;QAC9C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAqB,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAA4B,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,CAChB,wDAAwD,EACxD,mBAAmB,CACb,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAA4B,EAAE,QAAQ,EAAE,CAAC;IACnD,IAAI,MAAM,CAAC,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAC/C,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAK,IAAI,CAAC,QAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/E,OAAO,WAAW,CAChB,uCAAuC,EACvC,mBAAmB,CACb,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE;YACR;gBACE,cAAc,EAAE;oBACd,QAAQ,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;oBAC5C,UAAU,EAAE,qBAAqB;iBAClC;aACF;SACF;QACD,qBAAqB,EAAE,IAAI;KAC5B,CAAC;IACF,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,0EAA0E;AAE1E,MAAM,WAAW,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,WAAW,CAChB,8BAA8B,EAC9B,mBAAmB,CACb,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE;YACR,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;SAC9C;KACF,CAAC;IACF,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,cAAc,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,WAAW,CAChB,yBAAyB,EACzB,mBAAmB,CACb,CAAC;IACX,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,gCAAgC,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE;YACR;gBACE,UAAU,EAAE;oBACV,IAAI;oBACJ,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;oBAC9B,UAAU;iBACX;aACF;SACF;KACF,CAAC;IACF,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,cAAc,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,WAAW,CAChB,yBAAyB,EACzB,mBAAmB,CACb,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;KAC/D,CAAC;IACF,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,UAAU,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,MAAM,GACV,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAA4B;QACpC,aAAa,EAAE,EAAE;KAClB,CAAC;IACF,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;KAC1D,CAAC;IACF,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,MAAM,EACN,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,cAAc,EACtD,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,0EAA0E;AAE1E,MAAM,aAAa,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,IAAI,GACR,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B;QACtC,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,WAAW,CAAC,qBAAqB,EAAE,mBAAmB,CAAQ,CAAC;IACxE,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,KAAK,EACL,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,YAAY,GAAG,KAAK,EAC5D,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,WAAW,CAChB,qCAAqC,EACrC,mBAAmB,CACb,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,IAAI,CAChB,IAAI,EACJ,KAAK,EACL,QAAQ;QACN,kBAAkB,CAAC,MAAM,CAAC;QAC1B,aAAa;QACb,kBAAkB,CAAC,UAAU,CAAC,EAChC,IAAI,CACL,CAAQ,CAAC;AACZ,CAAC,CAAC;AAEF,0EAA0E;AAE1E,MAAM,CAAC,MAAM,oBAAoB,GAAmC;IAClE,OAAO;IACP,WAAW;IACX,UAAU;IACV,UAAU;IACV,WAAW;IACX,aAAa;IACb,WAAW;IACX,cAAc;IACd,cAAc;IACd,UAAU;IACV,aAAa;IACb,WAAW;CACZ,CAAC;AAEF,0EAA0E;AAE1E,MAAM,CAAC,MAAM,0BAA0B,GAA2B;IAChE;QACE,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,qBAAqB;gBAC5B,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,cAAc;gBAC3B,WAAW,EACT,sMAAsM;aACzM;YACD;gBACE,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,cAAc;gBACrB,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,YAAY;gBACzB,WAAW,EACT,4UAA4U;aAC/U;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,QAAQ;gBACrB,WAAW,EACT,+OAA+O;aAClP;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,oCAAoC;gBACjD,WAAW,EACT,iGAAiG;aACpG;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,qBAAqB;gBAC5B,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,UAAU;gBACvB,WAAW,EACT,qGAAqG;aACxG;YACD;gBACE,IAAI,EAAE,mBAAmB;gBACzB,KAAK,EAAE,0CAA0C;gBACjD,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,sBAAsB;gBACnC,WAAW,EACT,sNAAsN;aACzN;YACD;gBACE,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,uBAAuB;gBAC9B,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,yCAAyC;gBACtD,WAAW,EACT,uGAAuG;gBACzG,OAAO,EAAE,4CAA4C;aACtD;YACD;gBACE,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,mCAAmC;gBAC1C,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,6DAA6D;gBAC1E,WAAW,EACT,iJAAiJ;aACpJ;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,QAAQ;gBACf,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,KAAK;gBACf,WAAW,EACT,qGAAqG;gBACvG,WAAW,EACT,mUAAmU;aACtU;SACF;KACF;CACF,CAAC;AAEF,0EAA0E;AAE1E,MAAM,eAAe,GAAsB;IACzC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,4CAA4C;IACzD,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,UAAU;IACzB,QAAQ,EAAE,IAAI;IACd,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,iBAAiB;IAC9B,QAAQ,EAAE;QACR,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;QAC7B,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;KAClC;CACF,CAAC;AAEF,MAAM,WAAW,GAAsB;IACrC,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,SAAS;IAChB,WAAW,EACT,mJAAmJ;IACrJ,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,MAAM;IACrB,QAAQ,EAAE,IAAI;IACd,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,YAAY;CAC1B,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,oBAAoB,EAAE,mDAAmD;IACzE,aAAa,EACX,sEAAsE;IACxE,mBAAmB,EACjB,qEAAqE;IACvE,eAAe,EACb,oEAAoE;IACtE,qBAAqB,EACnB,oEAAoE;IACtE,SAAS,EAAE,oCAAoC;IAC/C,WAAW,EAAE,wDAAwD;IACrE,iBAAiB,EACf,sGAAsG;IACxG,YAAY,EAAE,2BAA2B;IACzC,SAAS,EAAE,4CAA4C;IACvD,iBAAiB,EAAE,gDAAgD;CACpE,CAAC;AAEF,0EAA0E;AAE1E,MAAM,CAAC,MAAM,2BAA2B,GAAqC;IAC3E,OAAO,EAAE;QACP,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,gCAAgC;QACzC,WAAW,EACT,iLAAiL;QACnL,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,gBAAgB;QACtB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC;QAC1C,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,gBAAgB;QACnC,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,qDAAqD;KAC/D;IAED,WAAW,EAAE;QACX,KAAK,EAAE,eAAe;QACtB,OAAO,EAAE,kBAAkB;QAC3B,WAAW,EACT,uFAAuF;QACzF,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC;QAC1C,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,kCAAkC;QACrD,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,yDAAyD;KACnE;IAED,UAAU,EAAE;QACV,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,0BAA0B;QACnC,WAAW,EACT,wPAAwP;QAC1P,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,gBAAgB;QACtB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QACzB,UAAU,EAAE;YACV,eAAe;YACf;gBACE,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,QAAQ;gBACf,WAAW,EACT,uJAAuJ;gBACzJ,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;gBACP,WAAW,EAAE,0DAA0D;aACxE;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,+CAA+C;QAClE,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,uEAAuE;KAC1E;IAED,UAAU,EAAE;QACV,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,uDAAuD;QAChE,WAAW,EACT,qPAAqP;QACvP,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QACzB,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,QAAQ;gBACf,WAAW,EACT,4cAA4c;gBAC9c,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;aACR;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,iEAAiE;QACpF,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,8EAA8E;KACjF;IAED,WAAW,EAAE;QACX,KAAK,EAAE,mBAAmB;QAC1B,OAAO,EAAE,4CAA4C;QACrD,WAAW,EACT,4OAA4O;QAC9O,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC;QAC/B,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EACT,+JAA+J;gBACjK,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;gBACP,WAAW,EACT,6GAA6G;aAChH;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,uBAAuB;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,4HAA4H;KAC/H;IAED,aAAa,EAAE;QACb,KAAK,EAAE,sBAAsB;QAC7B,OAAO,EAAE,gCAAgC;QACzC,WAAW,EACT,8IAA8I;QAChJ,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,gBAAgB;QACtB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC;QAC1C,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,4CAA4C;QAC/D,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,wDAAwD;KAClE;IAED,WAAW,EAAE;QACX,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,mDAAmD;QAC5D,WAAW,EACT,sLAAsL;QACxL,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC;QAC7C,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,MAAM;gBACb,WAAW,EACT,gSAAgS;gBAClS,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;gBACP,WAAW,EACT,yKAAyK;aAC5K;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,WAAW,EACT,qFAAqF;gBACvF,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;aACR;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,uBAAuB;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,+HAA+H;KAClI;IAED,cAAc,EAAE;QACd,KAAK,EAAE,iBAAiB;QACxB,OAAO,EAAE,gCAAgC;QACzC,WAAW,EACT,8JAA8J;QAChK,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC;QAC7C,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,YAAY;gBACnB,WAAW,EACT,0DAA0D;gBAC5D,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,QAAQ;gBACvB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;aACtB;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,cAAc;gBACrB,WAAW,EACT,6DAA6D;gBAC/D,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;aACR;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,WAAW,EACT,kGAAkG;gBACpG,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;aACR;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,uBAAuB;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,kGAAkG;KACrG;IAED,cAAc,EAAE;QACd,KAAK,EAAE,iBAAiB;QACxB,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EACT,4IAA4I;QAC9I,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC;QAC7C,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,YAAY;gBACnB,WAAW,EAAE,sCAAsC;gBACnD,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,QAAQ;gBACvB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;aACtB;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,uBAAuB;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,2DAA2D;KACrE;IAED,UAAU,EAAE;QACV,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,yDAAyD;QAClE,WAAW,EACT,yGAAyG;QAC3G,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC;QACxC,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,gBAAgB;gBACvB,WAAW,EACT,kEAAkE;gBACpE,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;gBACP,WAAW,EAAE,oDAAoD;aAClE;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,WAAW,EACT,iEAAiE;gBACnE,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;aACR;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,uBAAuB;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,yEAAyE;KAC5E;IAED,aAAa,EAAE;QACb,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE,uBAAuB;QAChC,WAAW,EACT,2IAA2I;QAC7I,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC;QAC3C,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,WAAW,EACT,4JAA4J;gBAC9J,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,CAAC;gBACP,QAAQ,EAAE,IAAI;aACf;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,kDAAkD;QACrE,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,uEAAuE;KAC1E;IAED,WAAW,EAAE;QACX,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,+BAA+B;QACxC,WAAW,EAAE,wDAAwD;QACrE,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC;QACnC,UAAU,EAAE;YACV,eAAe;YACf,WAAW;YACX;gBACE,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,aAAa;gBACpB,WAAW,EACT,wDAAwD;gBAC1D,QAAQ,EAAE,QAAQ;gBAClB,aAAa,EAAE,MAAM;gBACrB,QAAQ,EAAE,IAAI;gBACd,eAAe,EAAE,IAAI;aACtB;SACF;QACD,UAAU,EAAE,QAAQ;QACpB,iBAAiB,EAAE,wBAAwB;QAC3C,MAAM,EAAE,YAAY;QACpB,OAAO,EACL,mEAAmE;KACtE;CACF,CAAC;AAEF,0EAA0E;AAE1E,MAAM,CAAC,MAAM,yBAAyB,GAAmB;IACvD,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,cAAc;IACrB,OAAO,EACL,wGAAwG;IAC1G,WAAW,EACT,yuBAAyuB;IAC3uB,QAAQ,EAAE,cAAc;IACxB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,iDAAiD;IAC1D,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,EAAE;IACZ,cAAc,EAAE,QAAQ;IACxB,eAAe,EAAE,eAAe;IAChC,eAAe,EAAE;QACf,KAAK,EAAE;YACL,KAAK,EAAE,OAAO;YACd,WAAW,EAAE,iCAAiC;YAC9C,KAAK,EAAE,CAAC;SACT;QACD,KAAK,EAAE;YACL,KAAK,EAAE,OAAO;YACd,WAAW,EAAE,iDAAiD;YAC9D,KAAK,EAAE,CAAC;SACT;QACD,SAAS,EAAE;YACT,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,wBAAwB;YACrC,KAAK,EAAE,CAAC;SACT;KACF;IACD,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;CAC3C,CAAC"} |
| import type { ModuleAdapter } from "@robinpath/core"; | ||
| declare const GoogleFormsModule: ModuleAdapter; | ||
| export default GoogleFormsModule; | ||
| export { GoogleFormsModule }; | ||
| export { GoogleFormsFunctions, GoogleFormsFunctionMetadata, GoogleFormsModuleMetadata, GoogleFormsCredentialTypes, } from "./google-forms.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AASrD,QAAA,MAAM,iBAAiB,EAAE,aAQxB,CAAC;AAEF,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC"} |
| import { GoogleFormsFunctions, GoogleFormsFunctionMetadata, GoogleFormsModuleMetadata, GoogleFormsCredentialTypes, configureGoogleForms, } from "./google-forms.js"; | ||
| const GoogleFormsModule = { | ||
| name: "google-forms", | ||
| functions: GoogleFormsFunctions, | ||
| functionMetadata: GoogleFormsFunctionMetadata, | ||
| moduleMetadata: GoogleFormsModuleMetadata, | ||
| credentialTypes: GoogleFormsCredentialTypes, | ||
| configure: configureGoogleForms, | ||
| global: false, | ||
| }; | ||
| export default GoogleFormsModule; | ||
| export { GoogleFormsModule }; | ||
| export { GoogleFormsFunctions, GoogleFormsFunctionMetadata, GoogleFormsModuleMetadata, GoogleFormsCredentialTypes, } from "./google-forms.js"; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,iBAAiB,GAAkB;IACvC,IAAI,EAAE,cAAc;IACpB,SAAS,EAAE,oBAAoB;IAC/B,gBAAgB,EAAE,2BAA2B;IAC7C,cAAc,EAAE,yBAAyB;IACzC,eAAe,EAAE,0BAA0B;IAC3C,SAAS,EAAE,oBAAoB;IAC/B,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC"} |
+22
-9
| { | ||
| "name": "@robinpath/google-forms", | ||
| "version": "0.1.1", | ||
| "version": "0.3.0", | ||
| "publishConfig": { | ||
@@ -23,12 +23,19 @@ "access": "public" | ||
| "peerDependencies": { | ||
| "@robinpath/core": ">=0.20.0" | ||
| "@robinpath/core": ">=0.40.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@robinpath/core": "^0.30.1", | ||
| "@robinpath/core": "^0.40.0", | ||
| "typescript": "^5.6.0" | ||
| }, | ||
| "description": "Google Forms module for RobinPath.", | ||
| "description": "Google Forms (Forms API v1) integration — create forms, add/update/delete questions and sections via batchUpdate, convert to quiz, read responses. Supports delegated OAuth2 access tokens (with refresh-token rotation) or Google Workspace Domain-Wide Delegation via service-account JWT.", | ||
| "keywords": [ | ||
| "googleforms", | ||
| "productivity" | ||
| "productivity", | ||
| "google", | ||
| "forms", | ||
| "surveys", | ||
| "quizzes", | ||
| "oauth2", | ||
| "service-account", | ||
| "workspace" | ||
| ], | ||
@@ -38,7 +45,13 @@ "license": "MIT", | ||
| "category": "productivity", | ||
| "type": "integration", | ||
| "auth": "api-key", | ||
| "functionCount": 13, | ||
| "baseUrl": "https://forms.googleapis.com" | ||
| "type": "module", | ||
| "auth": "credential-vault", | ||
| "functionCount": 12, | ||
| "baseUrl": "https://forms.googleapis.com", | ||
| "language": "nodejs", | ||
| "platforms": [ | ||
| "cloud", | ||
| "cli", | ||
| "desktop" | ||
| ] | ||
| } | ||
| } |
+1
-1
@@ -22,3 +22,3 @@ # @robinpath/google-forms | ||
| ```bash | ||
| npm install @robinpath/google-forms | ||
| robinpath add @robinpath/google-forms | ||
| ``` | ||
@@ -25,0 +25,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Network access
Supply chain riskThis module accesses the network.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
91723
2394.51%10
400%1242
Infinity%2
100%4
100%