> ## Documentation Index
> Fetch the complete documentation index at: https://docs.acelabusa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Performance by Design. The Science of Modified Wood.

export const Quiz = ({contentIdentifier, apiBaseUrl, appBaseUrl, authPath = "/docs-auth", authMessageType = "acelab:docs-auth", quizPath = "/lms/learning-content/quiz?pagePath={contentIdentifier}", submissionPath = "/lms/learning-content/quiz/submissions?pagePath={contentIdentifier}", authTimeoutMs = 5000}) => {
  const QUIZ_PHASES = {
    Authenticating: "authenticating",
    Loading: "loading",
    Ready: "ready",
    Submitting: "submitting",
    Passed: "passed",
    Failed: "failed",
    Anonymous: "anonymous",
    Error: "error"
  };
  const TOKEN_STORAGE_KEY = "acelab:docs-auth-token";
  const localDocsHostnames = new Set(["localhost", "127.0.0.1", "[::1]"]);
  const isLocalDocsPreview = typeof window !== "undefined" && localDocsHostnames.has(window.location.hostname);
  const resolvedApiBaseUrl = apiBaseUrl || (isLocalDocsPreview ? "http://localhost:5100/api" : "https://acelab-api-prod-178528813198.us-east4.run.app/api");
  const resolvedAppBaseUrl = appBaseUrl || (isLocalDocsPreview ? "http://localhost:3000" : "https://app.acelabusa.com");
  const inferredContentIdentifier = typeof window === "undefined" ? "" : `/${window.location.pathname.split("/").filter(Boolean).join("/")}`;
  const resolvedContentIdentifier = String(contentIdentifier || "").trim() || inferredContentIdentifier;
  const trimTrailingSlash = value => String(value || "").replace(/\/+$/, "");
  const buildUrl = (baseUrl, path) => {
    const base = trimTrailingSlash(baseUrl);
    const normalizedPath = String(path || "").startsWith("/") ? path : `/${path}`;
    return `${base}${normalizedPath}`;
  };
  const buildContentPath = (pathTemplate, identifier) => pathTemplate.replace("{contentIdentifier}", encodeURIComponent(identifier));
  const readStoredToken = () => {
    try {
      return sessionStorage.getItem(TOKEN_STORAGE_KEY);
    } catch {
      return null;
    }
  };
  const storeToken = authToken => {
    try {
      if (authToken) {
        sessionStorage.setItem(TOKEN_STORAGE_KEY, authToken);
      } else {
        sessionStorage.removeItem(TOKEN_STORAGE_KEY);
      }
    } catch {}
  };
  const requestAuthToken = ({appBaseUrl: requestedAppBaseUrl, authPath: requestedAuthPath, authMessageType: requestedMessageType, timeoutMs}) => new Promise(resolve => {
    const appOrigin = new URL(requestedAppBaseUrl).origin;
    const iframe = document.createElement("iframe");
    let settled = false;
    const finish = authToken => {
      if (settled) return;
      settled = true;
      window.removeEventListener("message", onMessage);
      window.clearTimeout(timeoutId);
      iframe.remove();
      resolve(authToken);
    };
    const onMessage = event => {
      if (event.origin !== appOrigin || event.source !== iframe.contentWindow) {
        return;
      }
      if (!event.data || event.data.type !== requestedMessageType) {
        return;
      }
      finish(typeof event.data.token === "string" ? event.data.token : null);
    };
    const timeoutId = window.setTimeout(() => finish(null), timeoutMs);
    window.addEventListener("message", onMessage);
    iframe.src = buildUrl(requestedAppBaseUrl, requestedAuthPath);
    iframe.title = "Acelab sign-in check";
    iframe.setAttribute("aria-hidden", "true");
    iframe.style.display = "none";
    document.body.appendChild(iframe);
  });
  const parseErrorMessage = async (response, fallback) => {
    try {
      const body = await response.json();
      return body?.message || body?.error || fallback;
    } catch {
      return fallback;
    }
  };
  const validateQuiz = quizToValidate => {
    if (!quizToValidate || !Array.isArray(quizToValidate.questions) || quizToValidate.questions.length === 0) {
      throw new Error("This quiz does not have any questions yet.");
    }
    quizToValidate.questions.forEach(question => {
      if (question.id === undefined || !question.text || !Array.isArray(question.options) || question.options.length < 2 || question.options.some(option => option.id === undefined || !option.text)) {
        throw new Error("The quiz service returned an invalid question.");
      }
    });
    return quizToValidate;
  };
  const validateSubmissionResult = submissionResult => {
    if (!submissionResult || typeof submissionResult.passed !== "boolean" || !Number.isInteger(submissionResult.score) || !Number.isInteger(submissionResult.correctAnswerCount) || !Number.isInteger(submissionResult.incorrectAnswerCount)) {
      throw new Error("The quiz service returned an invalid grading result.");
    }
    return submissionResult;
  };
  const [phase, setPhase] = useState(QUIZ_PHASES.Authenticating);
  const [quiz, setQuiz] = useState(null);
  const [answers, setAnswers] = useState({});
  const [aiaNumber, setAiaNumber] = useState("");
  const [token, setToken] = useState(null);
  const [result, setResult] = useState(null);
  const [errorMessage, setErrorMessage] = useState("");
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const quizContainer = useRef(null);
  const authPopup = useRef(null);
  const authPopupPending = useRef(false);
  const authTokenCheckInFlight = useRef(false);
  const authQuizReloadInFlight = useRef(false);
  const scrollIntoView = () => {
    window.setTimeout(() => {
      quizContainer.current?.scrollIntoView({
        behavior: "smooth",
        block: "center"
      });
    }, 0);
  };
  const loadQuiz = async authToken => {
    if (!resolvedApiBaseUrl) {
      throw new Error("The quiz API URL has not been configured.");
    }
    const url = buildUrl(resolvedApiBaseUrl, buildContentPath(quizPath, resolvedContentIdentifier));
    const response = await fetch(url, {
      headers: {
        Accept: "application/json",
        Authorization: `Bearer ${authToken}`
      }
    });
    if (response.status === 401) {
      storeToken(null);
      setToken(null);
      setPhase(QUIZ_PHASES.Anonymous);
      return null;
    }
    if (!response.ok) {
      throw new Error(await parseErrorMessage(response, "We could not load this quiz."));
    }
    return validateQuiz(await response.json());
  };
  useEffect(() => {
    let cancelled = false;
    const initialize = async () => {
      setErrorMessage("");
      setResult(null);
      setAnswers({});
      setAiaNumber("");
      setQuiz(null);
      setCurrentQuestionIndex(0);
      if (!resolvedContentIdentifier) {
        setErrorMessage("This page is missing its quiz content identifier.");
        setPhase(QUIZ_PHASES.Error);
        return;
      }
      try {
        let authToken = readStoredToken();
        if (!authToken) {
          setPhase(QUIZ_PHASES.Authenticating);
          authToken = await requestAuthToken({
            appBaseUrl: resolvedAppBaseUrl,
            authPath,
            authMessageType,
            timeoutMs: authTimeoutMs
          });
        }
        if (cancelled) return;
        if (!authToken) {
          setPhase(QUIZ_PHASES.Anonymous);
          return;
        }
        storeToken(authToken);
        setToken(authToken);
        setPhase(QUIZ_PHASES.Loading);
        const loadedQuiz = await loadQuiz(authToken);
        if (cancelled || !loadedQuiz) return;
        setQuiz(loadedQuiz);
        setAiaNumber(loadedQuiz.aiaNumber || "");
        setPhase(QUIZ_PHASES.Ready);
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not load this quiz.");
        setPhase(QUIZ_PHASES.Error);
      }
    };
    initialize();
    return () => {
      cancelled = true;
    };
  }, [resolvedContentIdentifier, resolvedApiBaseUrl, resolvedAppBaseUrl, authPath, authMessageType, quizPath, authTimeoutMs]);
  useEffect(() => {
    let cancelled = false;
    const appOrigin = new URL(resolvedAppBaseUrl).origin;
    const loadQuizAfterAuthentication = async authToken => {
      if (!authToken || authQuizReloadInFlight.current) return;
      authQuizReloadInFlight.current = true;
      authPopupPending.current = false;
      authPopup.current = null;
      try {
        storeToken(authToken);
        setToken(authToken);
        setErrorMessage("");
        setResult(null);
        setAnswers({});
        setAiaNumber("");
        setQuiz(null);
        setCurrentQuestionIndex(0);
        setPhase(QUIZ_PHASES.Loading);
        const loadedQuiz = await loadQuiz(authToken);
        if (cancelled || !loadedQuiz) return;
        setQuiz(loadedQuiz);
        setAiaNumber(loadedQuiz.aiaNumber || "");
        setPhase(QUIZ_PHASES.Ready);
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not load this quiz.");
        setPhase(QUIZ_PHASES.Error);
      } finally {
        authQuizReloadInFlight.current = false;
      }
    };
    const onAuthMessage = event => {
      if (event.origin !== appOrigin || event.source !== authPopup.current || !event.data || event.data.type !== authMessageType) {
        return;
      }
      const authToken = typeof event.data.token === "string" ? event.data.token : null;
      if (!authToken) {
        authPopupPending.current = false;
        authPopup.current = null;
        storeToken(null);
        setToken(null);
        setPhase(QUIZ_PHASES.Anonymous);
        return;
      }
      loadQuizAfterAuthentication(authToken);
    };
    const recheckAuthAfterPopup = async () => {
      if (!authPopupPending.current || authTokenCheckInFlight.current || authQuizReloadInFlight.current) {
        return;
      }
      authTokenCheckInFlight.current = true;
      try {
        const authToken = await requestAuthToken({
          appBaseUrl: resolvedAppBaseUrl,
          authPath,
          authMessageType,
          timeoutMs: authTimeoutMs
        });
        if (cancelled || !authPopupPending.current || authQuizReloadInFlight.current) {
          return;
        }
        if (authToken) {
          await loadQuizAfterAuthentication(authToken);
        } else {
          if (!authPopup.current || authPopup.current.closed) {
            authPopupPending.current = false;
            authPopup.current = null;
          }
          setPhase(QUIZ_PHASES.Anonymous);
        }
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not check your Acelab sign-in.");
        setPhase(QUIZ_PHASES.Error);
      } finally {
        authTokenCheckInFlight.current = false;
      }
    };
    const onWindowFocus = () => {
      recheckAuthAfterPopup();
    };
    const onVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        recheckAuthAfterPopup();
      }
    };
    window.addEventListener("message", onAuthMessage);
    window.addEventListener("focus", onWindowFocus);
    document.addEventListener("visibilitychange", onVisibilityChange);
    return () => {
      cancelled = true;
      window.removeEventListener("message", onAuthMessage);
      window.removeEventListener("focus", onWindowFocus);
      document.removeEventListener("visibilitychange", onVisibilityChange);
    };
  }, [resolvedApiBaseUrl, authMessageType, authPath, authTimeoutMs, resolvedContentIdentifier, quizPath, resolvedAppBaseUrl]);
  const setAnswer = (questionId, optionId) => {
    setAnswers(current => ({
      ...current,
      [questionId]: optionId
    }));
  };
  const allQuestionsAnswered = quiz?.questions.every(question => answers[question.id] !== undefined) || false;
  const currentQuestion = quiz?.questions[currentQuestionIndex] || null;
  const currentQuestionAnswered = currentQuestion && answers[currentQuestion.id] !== undefined;
  const isLastQuestion = quiz && currentQuestionIndex === quiz.questions.length - 1;
  const showQuestion = questionIndex => {
    setCurrentQuestionIndex(questionIndex);
    scrollIntoView();
  };
  const previousQuestion = () => {
    if (currentQuestionIndex > 0) {
      showQuestion(currentQuestionIndex - 1);
    }
  };
  const nextQuestion = () => {
    if (currentQuestionAnswered && quiz && currentQuestionIndex < quiz.questions.length - 1) {
      showQuestion(currentQuestionIndex + 1);
    }
  };
  const submit = async event => {
    event.preventDefault();
    if (!quiz || !token || !allQuestionsAnswered) return;
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Submitting);
    try {
      const url = buildUrl(resolvedApiBaseUrl, buildContentPath(submissionPath, resolvedContentIdentifier));
      const response = await fetch(url, {
        method: "POST",
        headers: {
          Accept: "application/json",
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          aiaNumber,
          answers: quiz.questions.map(question => ({
            questionId: question.id,
            optionId: answers[question.id]
          }))
        })
      });
      if (response.status === 401) {
        storeToken(null);
        setToken(null);
        setPhase(QUIZ_PHASES.Anonymous);
        return;
      }
      if (!response.ok) {
        throw new Error(await parseErrorMessage(response, "We could not submit your answers. Please try again."));
      }
      const submissionResult = validateSubmissionResult(await response.json());
      setResult(submissionResult);
      setPhase(submissionResult.passed ? QUIZ_PHASES.Passed : QUIZ_PHASES.Failed);
      scrollIntoView();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "We could not submit your answers. Please try again.");
      setPhase(QUIZ_PHASES.Ready);
      scrollIntoView();
    }
  };
  const retry = () => {
    setResult(null);
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Ready);
    scrollIntoView();
  };
  const takeAgain = () => {
    setAnswers({});
    setCurrentQuestionIndex(0);
    retry();
  };
  const popupAuthPath = `${authPath}${authPath.includes("?") ? "&" : "?"}popup=1`;
  const loginUrl = typeof window === "undefined" ? buildUrl(resolvedAppBaseUrl, "/login") : `${buildUrl(resolvedAppBaseUrl, "/login")}?redirect=${encodeURIComponent(window.location.href)}`;
  const signupUrl = typeof window === "undefined" ? buildUrl(resolvedAppBaseUrl, "/signup") : `${buildUrl(resolvedAppBaseUrl, "/signup")}?redirect=${encodeURIComponent(window.location.href)}`;
  const popupLoginUrl = `${buildUrl(resolvedAppBaseUrl, "/docs-login")}?redirect=${encodeURIComponent(popupAuthPath)}`;
  const openAuthPopup = (event, popupUrl) => {
    event.preventDefault();
    const popup = window.open(popupUrl, "acelab-docs-auth");
    if (!popup) {
      setErrorMessage("Your browser blocked the sign-in tab. Allow pop-ups for this site and try again.");
      setPhase(QUIZ_PHASES.Anonymous);
      return;
    }
    authPopup.current = popup;
    authPopupPending.current = true;
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Authenticating);
    popup.focus();
  };
  const isBusy = phase === QUIZ_PHASES.Authenticating || phase === QUIZ_PHASES.Loading || phase === QUIZ_PHASES.Submitting;
  const resultQuestionCount = result ? result.correctAnswerCount + result.incorrectAnswerCount : 0;
  return <section ref={quizContainer} id={`quiz-${resolvedContentIdentifier || "unconfigured"}`} className="not-prose mt-10 rounded-xl border border-zinc-200 bg-zinc-50 px-5 py-8 text-zinc-950 dark:border-zinc-800 dark:bg-zinc-900 dark:text-white lg:px-10" aria-labelledby={`quiz-${resolvedContentIdentifier || "unconfigured"}-title`}>
      <div className="border-b border-zinc-200 pb-6 dark:border-zinc-800">
        <h2 id={`quiz-${resolvedContentIdentifier || "unconfigured"}-title`} className="m-0 text-3xl font-semibold">
          Take the Quiz
        </h2>
        <p className="mb-0 mt-3 text-zinc-600 dark:text-zinc-300">
          You can take the quiz as many times as you would like.
        </p>
      </div>

      <div className="pt-8" aria-live="polite" aria-busy={isBusy}>
        {(phase === QUIZ_PHASES.Authenticating || phase === QUIZ_PHASES.Loading) && <p className="m-0 text-zinc-600 dark:text-zinc-300">
            {phase === QUIZ_PHASES.Authenticating ? "Checking your Acelab sign-in..." : "Loading quiz..."}
          </p>}

        {phase === QUIZ_PHASES.Anonymous && <div>
            <p className="mt-0">
              Sign in or create an account to take the quiz.
            </p>
            {errorMessage && <p className="mt-3 text-red-700 dark:text-red-300" role="alert">
                {errorMessage}
              </p>}
            <div className="mt-4 flex flex-wrap gap-3">
              <a href={loginUrl} onClick={event => openAuthPopup(event, popupLoginUrl)} className="rounded-lg bg-emerald-600 px-5 py-3 font-medium text-white no-underline hover:bg-emerald-700">
                Sign in
              </a>
              <a href={signupUrl} className="rounded-lg border border-zinc-300 px-5 py-3 font-medium text-zinc-950 no-underline hover:bg-zinc-100 dark:border-zinc-700 dark:text-white dark:hover:bg-zinc-800">
                Create account
              </a>
            </div>
          </div>}

        {phase === QUIZ_PHASES.Error && <div role="alert">
            <p className="mt-0 font-semibold">Unable to load the quiz!</p>
            <p className="ml-1 mb-0 text-zinc-600 dark:text-zinc-300">
              Try refreshing the page! {errorMessage}
            </p>
          </div>}

        {phase === QUIZ_PHASES.Passed && <div className="flex flex-col items-center text-center">
            <p className="m-0 text-2xl font-semibold">Congratulations!</p>
            <p className="mb-0 mt-3 max-w-lg">
              You answered {result?.correctAnswerCount ?? 0} of{" "}
              {resultQuestionCount} questions correctly and passed with a score
              of {result?.score ?? 0}%.
            </p>
            <p className="mb-0 mt-3 max-w-lg text-zinc-600 dark:text-zinc-300">
              Your continuing education certificate will be emailed to you
              shortly.
            </p>
            <button type="button" className="mt-5 border-0 bg-transparent font-semibold text-emerald-700 underline hover:no-underline dark:text-emerald-400" onClick={takeAgain}>
              Take Quiz Again
            </button>
          </div>}

        {phase === QUIZ_PHASES.Failed && <div className="flex flex-col items-center text-center">
            <p className="m-0 text-2xl font-semibold">Oops!</p>
            <p className="mb-0 mt-3 max-w-md">
              You answered {result?.correctAnswerCount ?? 0} of{" "}
              {resultQuestionCount} questions correctly and scored{" "}
              {result?.score ?? 0}%.
            </p>
            <button type="button" className="mt-5 rounded-lg bg-emerald-600 px-8 py-3 font-semibold text-white hover:bg-emerald-700" onClick={takeAgain}>
              Try Again
            </button>
          </div>}

        {(phase === QUIZ_PHASES.Ready || phase === QUIZ_PHASES.Submitting) && quiz && currentQuestion && <form onSubmit={submit}>
              {errorMessage && <div role="alert" className="mb-6 rounded-lg border border-red-300 bg-red-50 px-4 py-3 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100">
                  {errorMessage}
                </div>}

              <div className="mb-8">
                <div className="mb-2 text-sm font-medium text-zinc-600 dark:text-zinc-300">
                  <span>
                    Question {currentQuestionIndex + 1} of{" "}
                    {quiz.questions.length}
                  </span>
                </div>
                <div role="progressbar" aria-label="Quiz progress" aria-valuemin={1} aria-valuemax={quiz.questions.length} aria-valuenow={currentQuestionIndex + 1} className="h-2 overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-700">
                  <div className="h-full rounded-full bg-emerald-500 transition-all duration-300" style={{
    width: `${(currentQuestionIndex + 1) / quiz.questions.length * 100}%`
  }} />
                </div>
              </div>

              <fieldset key={currentQuestion.id} className="m-0 border-0 p-0">
                <legend className="mb-6 flex items-start gap-3 text-lg font-medium">
                  <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-emerald-500 font-bold text-white">
                    {currentQuestionIndex + 1}
                  </span>
                  <span>{currentQuestion.text}</span>
                </legend>

                <div className="space-y-3 pl-12">
                  {currentQuestion.options.map((option, optionIndex) => {
    const inputId = `quiz-${resolvedContentIdentifier}-${currentQuestion.id}-${option.id}`;
    const selected = answers[currentQuestion.id] === option.id;
    return <label key={option.id} htmlFor={inputId} className={`flex cursor-pointer items-start gap-3 rounded-lg border px-4 py-3 transition-colors ${selected ? "border-emerald-500 bg-emerald-50 font-medium dark:bg-emerald-950" : "border-zinc-200 bg-white hover:border-zinc-400 dark:border-zinc-700 dark:bg-zinc-950 dark:hover:border-zinc-500"}`}>
                        <input id={inputId} type="radio" name={`quiz-question-${currentQuestion.id}`} value={option.id} checked={selected} required={optionIndex === 0} disabled={phase === QUIZ_PHASES.Submitting} className="mt-1 h-4 w-4 accent-emerald-600" onChange={() => setAnswer(currentQuestion.id, option.id)} />
                        <span>{option.text}</span>
                      </label>;
  })}
                </div>
              </fieldset>

              {isLastQuestion && <div className="mt-8 border-t border-zinc-200 pt-6 dark:border-zinc-800">
                  <label htmlFor={`quiz-${resolvedContentIdentifier}-aia-number`} className="block text-sm font-semibold">
                    AIA Number (optional)
                  </label>
                  <input id={`quiz-${resolvedContentIdentifier}-aia-number`} type="text" value={aiaNumber} maxLength={100} disabled={phase === QUIZ_PHASES.Submitting} className="mt-2 w-full rounded-lg border border-zinc-300 bg-white px-4 py-3 text-zinc-950 outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white" onChange={event => setAiaNumber(event.target.value)} />
                  <p className="mb-0 mt-2 text-sm text-zinc-600 dark:text-zinc-300">
                    This number will be saved to your Acelab profile and used
                    for your continuing education certificate.
                  </p>
                </div>}

              <div className="flex items-center pt-8 justify-between gap-4 border-zinc-200 dark:border-zinc-800">
                {currentQuestionIndex > 0 ? <button type="button" disabled={phase === QUIZ_PHASES.Submitting} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5" onClick={previousQuestion}>
                    Back
                  </button> : <span />}

                {isLastQuestion ? <button type="submit" disabled={phase === QUIZ_PHASES.Submitting || !allQuestionsAnswered} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5">
                    {phase === QUIZ_PHASES.Submitting ? "Submitting..." : "Submit your answers"}
                  </button> : <button type="button" disabled={!currentQuestionAnswered} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5" onClick={nextQuestion}>
                    Next
                  </button>}
              </div>
            </form>}
      </div>
    </section>;
};

## Introduction

## About

As advances in treatment processes have made wood an even more viable building material, it has become essential to the construction industry as the building material of the 21st century.<br /><br />In this course we will provide an overview of the benefits and limitations of wood. Review advances in wood modification processes and consider the environmental impact of modified wood use in construction.

Learning Objectives:

* Define current modification techniques of wood.
* Refine product selection to ensure key specifications are met for project requirements.
* Establish the environmental impact of modified wood construction vs. non wood options.
* Learn about a state of the art modification process for enhancing wood products.

### Course Information

Course name : Performance by Design. The Science of Modified Wood.<br />Course number : 001<br />Credit Type : 1 LU|Elective<br />Number of Credits : 1<br />Provider name : Timber Trading Group<br />Provider number : 404108287

## Part 1: Intro Objectives Case for Wood

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/S7z40g2HEO8?si=gt71f0e7hHfeuZUw" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## Part 2: Modification Techniques

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/dE3hRzcIVhU?si=bx7JcGReWl6gT0Ub" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## Part 3: IAQ Species Applications

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/CQUktysy9ik?si=Ns8vPiWiEFRCZEHi" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## Part 4: Key Takeaways

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/Q05I1IfgMRA?si=Qh5sbsMKnKRZdUue" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## Quiz (required)

To receive AIA CEU (1 LU), please complete the 10 questions below. You must get at least 70% correct answers. If you do not succeed, you may retake the quiz.

<Quiz />

Ready to dive deeper into how LP Building Solutions are revolutionizing the architectural landscape? Click below to explore their innovative approaches, diverse portfolio, and how we can collaborate to bring your vision to life. Let's shape the future of architecture together.

[Learn more](https://app.acelabusa.com/manufacturer/lp-building-solutions-f1260ee10c9f4621ba3a29568aa9)
