text: import React from 'react';
  import { getDynamicStyles } from 'jss';
  import mergeClasses from '../mergeClasses';
  import multiKeyStore from './multiKeyStore';
  import useTheme from '../useTheme';
  import { StylesContext } from '../StylesProvider';
  import { increment } from './indexCounter';
  import getStylesCreator from '../getStylesCreator';
  import noopTheme from '../getStylesCreator/noopTheme';
  
  function getClasses({ state, stylesOptions }, classes, Component) {
    if (stylesOptions.disableGeneration) {
      return classes || {};
    }
  
    if (!state.cacheClasses) {
      state.cacheClasses = {
        // Cache for the finalized classes value.
        value: null,
        // Cache for the last used classes prop pointer.
        lastProp: null,
        // Cache for the last used rendered classes pointer.
        lastJSS: {},
      };
    }
  
    // Tracks if either the rendered classes or classes prop has changed,
    // requiring the generation of a new finalized classes object.
    let generate = false;
  
    if (state.classes !== state.cacheClasses.lastJSS) {
      state.cacheClasses.lastJSS = state.classes;
      generate = true;
    }
    if (classes !== state.cacheClasses.lastProp) {
      state.cacheClasses.lastProp = classes;
      generate = true;
    }
  
    if (generate) {
      state.cacheClasses.value = mergeClasses({
        baseClasses: state.cacheClasses.lastJSS,
        newClasses: classes,
        Component,
      });
    }
  
    return state.cacheClasses.value;
  }
  
  function attach({ state, theme, stylesOptions, stylesCreator, name }, props) {
    if (stylesOptions.disableGeneration) {
      return;
    }
  
    let sheetManager = multiKeyStore.get(stylesOptions.sheetsManager, stylesCreator, theme);
  
    if (!sheetManager) {
      sheetManager = {
        refs: 0,
        staticSheet: null,
        dynamicStyles: null,
      };
      multiKeyStore.set(stylesOptions.sheetsManager, stylesCreator, theme, sheetManager);
    }
  
    const options = {
      ...stylesCreator.options,
      ...stylesOptions,
      theme,
      flip: typeof stylesOptions.flip === 'boolean' ? stylesOptions.flip : theme.direction === 'rtl',
    };
    options.generateId = options.serverGenerateClassName || options.generateClassName;
  
    const sheetsRegistry = stylesOptions.sheetsRegistry;
  
    if (sheetManager.refs === 0) {
      let staticSheet;
  
      if (stylesOptions.sheetsCache) {
        staticSheet = multiKeyStore.get(stylesOptions.sheetsCache, stylesCreator, theme);
      }
  
      const styles = stylesCreator.create(theme, name);
  
      if (!staticSheet) {
        staticSheet = stylesOptions.jss.createStyleSheet(styles, {
          link: false,
          ...options,
        });
        staticSheet.attach();
  
        if (stylesOptions.sheetsCache) {
          multiKeyStore.set(stylesOptions.sheetsCache, stylesCreator, theme, staticSheet);
        }
      }
  
      if (sheetsRegistry) {
        sheetsRegistry.add(staticSheet);
      }
  
      sheetManager.staticSheet = staticSheet;
      sheetManager.dynamicStyles = getDynamicStyles(styles);
    }
  
    if (sheetManager.dynamicStyles) {
      const dynamicSheet = stylesOptions.jss.createStyleSheet(sheetManager.dynamicStyles, {
        link: true,
        ...options,
      });
  
      dynamicSheet.update(props);
      dynamicSheet.attach();
  
      state.dynamicSheet = dynamicSheet;
      state.classes = mergeClasses({
        baseClasses: sheetManager.staticSheet.classes,
        newClasses: dynamicSheet.classes,
      });
  
      if (sheetsRegistry) {
        sheetsRegistry.add(dynamicSheet);
      }
    } else {
      state.classes = sheetManager.staticSheet.classes;
    }
  
    sheetManager.refs += 1;
  }
  
  function update({ state }, props) {
    if (state.dynamicSheet) {
      state.dynamicSheet.update(props);
    }
  }
  
  function detach({ state, theme, stylesOptions, stylesCreator }) {
    if (stylesOptions.disableGeneration) {
      return;
    }
  
    const sheetManager = multiKeyStore.get(stylesOptions.sheetsManager, stylesCreator, theme);
    sheetManager.refs -= 1;
    const sheetsRegistry = stylesOptions.sheetsRegistry;
  
    if (sheetManager.refs === 0) {
      multiKeyStore.delete(stylesOptions.sheetsManager, stylesCreator, theme);
      stylesOptions.jss.removeStyleSheet(sheetManager.staticSheet);
      if (sheetsRegistry) {
        sheetsRegistry.remove(sheetManager.staticSheet);
      }
    }
  
    if (state.dynamicSheet) {
      stylesOptions.jss.removeStyleSheet(state.dynamicSheet);
      if (sheetsRegistry) {
        sheetsRegistry.remove(state.dynamicSheet);
      }
    }
  }
  
  function useSynchronousEffect(func, values) {
    const key = React.useRef([]);
    let output;
  
    // Store "generation" key. Just returns a new object every time
    const currentKey = React.useMemo(() => ({}), values); // eslint-disable-line react-hooks/exhaustive-deps
  
    // "the first render", or "memo dropped the value"
    if (key.current !== currentKey) {
      key.current = currentKey;
      output = func();
    }
  
    React.useEffect(
      () => () => {
        if (output) {
          output();
        }
      },
      [currentKey], // eslint-disable-line react-hooks/exhaustive-deps
    );
  }
  
  export default function makeStyles(stylesOrCreator, options = {}) {
    const {
      // alias for classNamePrefix, if provided will listen to theme (required for theme.components[name].overrides)
      name,
      // Help with debuggability.
      classNamePrefix: classNamePrefixOption,
      Component,
      defaultTheme = noopTheme,
      ...stylesOptions2
    } = options;
    const stylesCreator = getStylesCreator(stylesOrCreator);
    const classNamePrefix = name || classNamePrefixOption || 'makeStyles';
    stylesCreator.options = {
      index: increment(),
      name,
      meta: classNamePrefix,
      classNamePrefix,
    };
  
    const useStyles = (props = {}) => {
      const theme = useTheme() || defaultTheme;
      const stylesOptions = {
        ...React.useContext(StylesContext),
        ...stylesOptions2,
      };
  
      const instance = React.useRef();
      const shouldUpdate = React.useRef();
  
      useSynchronousEffect(() => {
        const current = {
          name,
          state: {},
          stylesCreator,
          stylesOptions,
          theme,
        };
  
        attach(current, props);
  
        shouldUpdate.current = false;
        instance.current = current;
        return () => {
          detach(current);
        };
      }, [theme, stylesCreator]);
  
      React.useEffect(() => {
        if (shouldUpdate.current) {
          update(instance.current, props);
        }
        shouldUpdate.current = true;
      });
  
      const classes = getClasses(instance.current, props.classes, Component);
      if (process.env.NODE_ENV !== 'production') {
        // eslint-disable-next-line react-hooks/rules-of-hooks
        React.useDebugValue(classes);
      }
      if (process.env.NODE_ENV !== 'production') {
        const supportedComponents = [
          'MuiAvatar',
          'MuiBadge',
          'MuiButton',
          'MuiButtonGroup',
          'MuiChip',
          'MuiDivider',
          'MuiFab',
          'MuiPaper',
          'MuiToolbar',
          'MuiTypography',
          'MuiAlert',
          'MuiPagination',
          'MuiPaginationItem',
          'MuiSkeleton',
          'MuiTimelineDot',
        ];
  
        if (
          name &&
          supportedComponents.indexOf(name) >= 0 &&
          props.variant &&
          !classes[props.variant]
        ) {
          console.error(
            [
              `Material-UI: You are using a variant value \`${props.variant}\` for which you didn't define styles.`,
              // TODO: switch to material-ui.com when v5 is released
              `Please create a new variant matcher in your theme for this variant. To learn more about matchers visit https://next.material-ui.com/r/custom-component-variants.`,
            ].join('\n'),
          );
        }
      }
  
      return classes;
    };
  
    return useStyles;
  }
  