Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: npm install not working without distutils #1513

Open
5 tasks done
devtobi opened this issue Nov 21, 2024 · 12 comments
Open
5 tasks done

[Bug]: npm install not working without distutils #1513

devtobi opened this issue Nov 21, 2024 · 12 comments

Comments

@devtobi
Copy link

devtobi commented Nov 21, 2024

Version

  • I'm using version 1.16

Known issues

  • I've checked Known issues

Existing issues

  • I've checked Existing issues

Advanced Preferences

  • I've checked Advanced Preferences

What operating system are you using?

macOS

Operating System Version

macOS 15.1.1

Reproduction steps

  1. I installed suggested node version 20.18.0
  2. Checked out the source code
  3. Run npm install inside the root directory

Reproduces how often: [What percentage of the time does it reproduce?]

Expected Behavior

npm install should run just fine.

Actual Behavior

npm installfails and I cannot setup the repository for development.

Relevant log output

File "/Users/devtobi/Development/repositories/github/stretchly/node_modules/node-gyp/gyp/gyp_main.py", line 42, in <module>
npm error     import gyp  # noqa: E402
npm error     ^^^^^^^^^^
npm error   File "/Users/devtobi/Development/repositories/github/stretchly/node_modules/node-gyp/gyp/pylib/gyp/__init__.py", line 9, in <module>
npm error     import gyp.input
npm error   File "/Users/devtobi/Development/repositories/github/stretchly/node_modules/node-gyp/gyp/pylib/gyp/input.py", line 19, in <module>
npm error     from distutils.version import StrictVersion
npm error ModuleNotFoundError: No module named 'distutils'

Code of Conduct

  • I agree to follow this project's Code of Conduct
@devtobi
Copy link
Author

devtobi commented Nov 21, 2024

I actually already found the root cause for this problem. It looks like some dependency stretchly uses depends on node-gyp and calls some python code when executing.
This means it looks like Python needs to be installed on the local machine.
When using a up to date Python version like 3.12 or 3.13, distutils is no longer included out of the box and has to be installed manually. On mac this was as easy as running brew install python-setuptools but I don't know if its more complex for other operating systems.

The documentation in the README should include this information:

  • Python 3.x is required on the local machine
  • If a Python version higher than 3.12 is used python setuptools have to be additionally installed.

After installing those tools I can run npm install just fine.

@devtobi
Copy link
Author

devtobi commented Nov 21, 2024

As stated above npm install works fine now but I still get issues when trying to run the provided tests scripts.
I suppose start, dev, test and lintq are all relevant npm scripts when developing and trying to contribute to this project.
However only test is currently running on my machine.
Here are the logs for the other tasks:

start (in this case the app starts of for a short time and I see the language selection welcome screen, but the app instantly crashes):

2024-11-21 23:01:41.863 Electron[69539:715519] +[IMKClient subclass]: chose IMKClient_Modern
2024-11-21 23:01:41.863 Electron[69539:715519] +[IMKInputSession subclass]: chose IMKInputSession_Modern
2024-11-21 23:01:42.414 Electron[69539:715519] MacosNotificationState: FocusStatusCenter API available
2024-11-21 23:01:42.446 Electron[69539:715519] MacosNotificationState: promise created
/Users/tobias/Development/repositories/github/stretchly/node_modules/electron/dist/Electron.app/Contents/MacOS/Electron exited with signal SIGABRT

dev:

cross-env NODE_ENV=development electron . --trace-warnings --trace-deprecation --enable-logging --remote-debugging-port=9222

sh: /Users/devtobi/Development/repositories/github/stretchly/node_modules/.bin/cross-env: Permission denied

=> chmod -R a+x node_modules fixes this issue (but is this really the way to go?) and then again leads to same error as in start

lint has same permission error as in dev and is "fixed" by manually calling chmod on the binaries inside the node_modules folder.

@hovancik Are there any other npm scripts I should test?

@hovancik
Copy link
Owner

hovancik commented Nov 22, 2024

Hi @devtobi , I don't have supported macbook, but I have latest macOS on my old macbook with https://dortania.github.io/OpenCore-Legacy-Patcher/, so this might not be absolutely relevant.

I don't ever remember having to do anything more that npm i on my macbook. Here is for example how I build the app for distribution on Github Actions: https://github.com/hovancik/stretchly/blob/trunk/.github/workflows/build.yml

For mac, I only make sure that command line tools are installed and then as you mention with newer python, i do pip install setuptools.

If you updated your mac recently, I know it usually breaks the command line tools, so I had to remove them and install again after each OS upgrade.

But I do not use my macbook actively for many years now.

@devtobi
Copy link
Author

devtobi commented Nov 23, 2024

After reinstalling my command line tools the permission errors are gone and I do not have to chmod anymore. However the app still crashes instantly after launching either via start or dev.
I checked the Stretchly log file under /Library/Logs/Stretchly/main.log but nothing useful there.

Here is the whole log output when running npm run dev:

Log Output
DevTools listening on ws://127.0.0.1:9222/devtools/browser/88cdfd94-11f9-446c-82cd-46b737e920f8
12:33:47.990Stretchly: initializing...
12:33:47.997Stretchly: loading preferences
12:33:48.001Stretchly: starting Idle time monitoring
12:33:48.005Stretchly: starting Do Not Disturb monitoring
[60192:1123/123348.028392:WARNING:viz_main_impl.cc(85)] VizNullHypothesis is disabled (not a warning)
i18next: hasLoadedNamespace: i18next was not initialized undefined
i18next::translator: key "miniBreakIdeas" for languages "en" won't get resolved as namespace "translation" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!
i18next::translator: missingKey en translation miniBreakIdeas miniBreakIdeas
i18next::translator: missingKey undefined translation miniBreakIdeas.0.text miniBreakIdeas.0.text
i18next::translator: missingKey undefined translation miniBreakIdeas.1.text miniBreakIdeas.1.text
i18next::translator: missingKey undefined translation miniBreakIdeas.2.text miniBreakIdeas.2.text
i18next::translator: missingKey undefined translation miniBreakIdeas.3.text miniBreakIdeas.3.text
i18next::translator: missingKey undefined translation miniBreakIdeas.4.text miniBreakIdeas.4.text
i18next::translator: missingKey undefined translation miniBreakIdeas.5.text miniBreakIdeas.5.text
i18next::translator: missingKey undefined translation miniBreakIdeas.6.text miniBreakIdeas.6.text
i18next::translator: missingKey undefined translation miniBreakIdeas.7.text miniBreakIdeas.7.text
i18next::translator: missingKey undefined translation miniBreakIdeas.8.text miniBreakIdeas.8.text
i18next::translator: missingKey undefined translation miniBreakIdeas.9.text miniBreakIdeas.9.text
i18next::translator: missingKey undefined translation miniBreakIdeas.10.text miniBreakIdeas.10.text
i18next::translator: missingKey undefined translation miniBreakIdeas.11.text miniBreakIdeas.11.text
i18next::translator: missingKey undefined translation miniBreakIdeas.12.text miniBreakIdeas.12.text
i18next::translator: missingKey undefined translation miniBreakIdeas.13.text miniBreakIdeas.13.text
i18next::translator: missingKey en translation longBreakIdeas longBreakIdeas
i18next::translator: missingKey undefined translation longBreakIdeas.0.title longBreakIdeas.0.title
i18next::translator: missingKey undefined translation longBreakIdeas.0.text longBreakIdeas.0.text
i18next::translator: missingKey undefined translation longBreakIdeas.1.title longBreakIdeas.1.title
i18next::translator: missingKey undefined translation longBreakIdeas.1.text longBreakIdeas.1.text
i18next::translator: missingKey undefined translation longBreakIdeas.2.title longBreakIdeas.2.title
i18next::translator: missingKey undefined translation longBreakIdeas.2.text longBreakIdeas.2.text
i18next::translator: missingKey undefined translation longBreakIdeas.3.title longBreakIdeas.3.title
i18next::translator: missingKey undefined translation longBreakIdeas.3.text longBreakIdeas.3.text
i18next::translator: missingKey undefined translation longBreakIdeas.4.title longBreakIdeas.4.title
i18next::translator: missingKey undefined translation longBreakIdeas.4.text longBreakIdeas.4.text
i18next::translator: missingKey undefined translation longBreakIdeas.5.title longBreakIdeas.5.title
i18next::translator: missingKey undefined translation longBreakIdeas.5.text longBreakIdeas.5.text
i18next::translator: missingKey undefined translation longBreakIdeas.6.title longBreakIdeas.6.title
i18next::translator: missingKey undefined translation longBreakIdeas.6.text longBreakIdeas.6.text
i18next::translator: missingKey undefined translation longBreakIdeas.7.title longBreakIdeas.7.title
i18next::translator: missingKey undefined translation longBreakIdeas.7.text longBreakIdeas.7.text
i18next::translator: missingKey undefined translation longBreakIdeas.8.title longBreakIdeas.8.title
i18next::translator: missingKey undefined translation longBreakIdeas.8.text longBreakIdeas.8.text
i18next::translator: missingKey undefined translation longBreakIdeas.9.title longBreakIdeas.9.title
i18next::translator: missingKey undefined translation longBreakIdeas.9.text longBreakIdeas.9.text
i18next::translator: missingKey undefined translation longBreakIdeas.10.title longBreakIdeas.10.title
i18next::translator: missingKey undefined translation longBreakIdeas.10.text longBreakIdeas.10.text
i18next::translator: missingKey undefined translation longBreakIdeas.11.title longBreakIdeas.11.title
i18next::translator: missingKey undefined translation longBreakIdeas.11.text longBreakIdeas.11.text
i18next::translator: missingKey undefined translation longBreakIdeas.12.title longBreakIdeas.12.title
i18next::translator: missingKey undefined translation longBreakIdeas.12.text longBreakIdeas.12.text
i18next::translator: missingKey undefined translation longBreakIdeas.13.title longBreakIdeas.13.title
i18next::translator: missingKey undefined translation longBreakIdeas.13.text longBreakIdeas.13.text
12:33:48.114Stretchly: loading default break ideas
i18next::translator: missingKey undefined translation main.toolTipHeader main.toolTipHeader
i18next::translator: missingKey undefined translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey undefined translation utils.inAbout utils.inAbout
i18next::translator: missingKey undefined translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey undefined translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey undefined translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey undefined translation utils.inAbout utils.inAbout
i18next::translator: missingKey undefined translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey undefined translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey undefined translation main.toMicrobreak main.toMicrobreak
i18next::translator: missingKey undefined translation main.toBreak main.toBreak
i18next::translator: missingKey undefined translation main.skipToTheNext main.skipToTheNext
i18next::translator: missingKey undefined translation main.pause main.pause
i18next::translator: missingKey undefined translation utils.minutes utils.minutes
i18next::translator: missingKey undefined translation main.forHour main.forHour
i18next::translator: missingKey undefined translation main.for2Hours main.for2Hours
i18next::translator: missingKey undefined translation main.for5Hours main.for5Hours
i18next::translator: missingKey undefined translation main.untilMorning main.untilMorning
i18next::translator: missingKey undefined translation main.indefinitely main.indefinitely
i18next::translator: missingKey undefined translation main.resetBreaks main.resetBreaks
i18next::translator: missingKey undefined translation main.preferences main.preferences
i18next::translator: missingKey undefined translation main.quitStretchly main.quitStretchly
i18next::translator: missingKey en translation main.toolTipHeader main.toolTipHeader
i18next::translator: missingKey en translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey en translation utils.inAbout utils.inAbout
i18next::translator: missingKey en translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey en translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey en translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey en translation utils.inAbout utils.inAbout
i18next::translator: missingKey en translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey en translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey en translation main.toMicrobreak main.toMicrobreak
i18next::translator: missingKey en translation main.toBreak main.toBreak
i18next::translator: missingKey en translation main.skipToTheNext main.skipToTheNext
i18next::translator: missingKey en translation main.pause main.pause
i18next::translator: missingKey en translation utils.minutes utils.minutes
i18next::translator: missingKey en translation main.forHour main.forHour
i18next::translator: missingKey en translation main.for2Hours main.for2Hours
i18next::translator: missingKey en translation main.for5Hours main.for5Hours
i18next::translator: missingKey en translation main.untilMorning main.untilMorning
i18next::translator: missingKey en translation main.indefinitely main.indefinitely
i18next::translator: missingKey en translation main.resetBreaks main.resetBreaks
i18next::translator: missingKey en translation main.preferences main.preferences
i18next::translator: missingKey en translation main.quitStretchly main.quitStretchly
i18next::backendConnector: loaded namespace translation for language en {
  main: {
    toolTipHeader: 'Stretchly - The break time reminder app',
    microbreakIn: "Mini Break in $t(utils.seconds, {'count': {{seconds}} })",
    breakIn: "Long Break in $t(utils.seconds, {'count': {{seconds}} })",
    resumingBreaks: 'Resuming breaks',
    downloadLatestVersion: 'Download latest version',
    toBreak: 'Long Break',
    toMicrobreak: 'Mini Break',
    skipToTheNext: 'Skip to the next',
    resume: 'Resume Breaks',
    pause: 'Pause Breaks',
    forHour: '1 hour',
    for2Hours: '2 hours',
    for5Hours: '5 hours',
    untilMorning: 'Until morning',
    indefinitely: 'Indefinitely',
    resetBreaks: 'Reset Breaks',
    quitStretchly: 'Quit Stretchly',
    restoreDefaults: 'Restore defaults',
    warning: 'This will restore app defaults and all your settings will be lost.',
    continue: 'Continue',
    cancel: 'Cancel',
    preferences: 'Preferences',
    contributorPreferences: 'Contributor Preferences',
    syncPreferences: 'Sync Preferences'
  },
  break: {
    postpone: 'Postpone this break',
    skip: 'Skip this break',
    title: 'Time to take a break!'
  },
  preferences: {
    title: 'Stretchly Preferences',
    nav: {
      settings: 'Settings',
      schedule: 'Schedule',
      theme: 'Theme',
      about: 'About',
      heart: 'Love Stretchly'
    },
    settings: {
      openAtLogin: 'Start Stretchly automatically when logging in',
      showBreaksIn: 'Shows breaks in:',
      window: 'Window',
      fullscreen: 'Full screen',
      showIdeas: 'Show exercise tips during breaks',
      allScreens: 'Shows breaks on all monitors',
      monitorIdleTime: 'Monitor system idle time (breaks are paused if system is idle).',
      monitorDnd: 'Show breaks even in Do Not Disturb mode',
      language: 'Select language:',
      restoreDefaults: 'Restore defaults'
    },
    schedule: {
      miniBreaks: 'Mini Breaks:',
      miniBreaksInfo: 'Mini Breaks are short breaks taken regularly to give you a chance to stretch and relax.',
      enableMiniBreaks: 'Enable Mini Breaks',
      breakFor: 'Break for:',
      every: 'Every:',
      showNotificationBeforeMiniBreak: 'Show notification before Mini Break starts',
      enablePostponeMini: 'Enable Postponement for Mini Break',
      longBreaks: 'Long Breaks:',
      longBreaksInfo: 'Long Breaks are taken less regularly, but are of greater duration, allowing you to take an extended break from your work.',
      enableLongBreaks: 'Enable Long Breaks',
      showNotificationBeforeLongBreak: 'Show notification before Long Break starts',
      enablePostponeLong: 'Enable Postponement for Long Break',
      strictMode: 'Strict Mode:',
      strictModeInfo: 'Strict Mode prevents you from skipping either Mini Breaks or Long Breaks and is designed to help discipline.',
      enableStrictMini: 'Enable Strict Mode for Mini Breaks',
      enableStrictLong: 'Enable Strict Mode for Long Breaks',
      cantDisableBoth: 'It is not possible to disable both types of breaks'
    },
    theme: {
      appearance: 'Appearance:',
      greenClouds: 'Green clouds',
      autumnBeBlessed: 'Autumn be blessed',
      graphiteCrystal: 'Graphite crystal',
      coffeeKisses: 'Coffee kisses',
      morningSwim: 'Morning swim',
      transparentMode: 'Enable transparency',
      sounds: 'Sounds:',
      enableSounds: 'Enable sounds',
      crystalGlass: 'Crystal glass',
      windChime: 'Wind chime',
      ticToc: 'Tic toc',
      reverie: 'Reverie',
      menubarIcon: 'Menubar icon:',
      colour: 'Colour',
      monochrome: 'Monochrome',
      invertedMonochrome: 'Inverted Monochrome',
      snowWhite: 'Snow white'
    },
    about: {
      tagline: 'The break time reminder app',
      version: 'Version ',
      latestVersion: 'Latest version ',
      checkNewVersion: 'Automatically check for app updates',
      learnMore: 'To learn more about Stretchly features, view a tutorial, download the latest version or contact us for support, ',
      ourWebsite: 'visit our website',
      dot: '.',
      developedBy: 'Developed by',
      janH: 'Jan Hovancik',
      designedBy: 'Icon and UI design by Colin Shanley'
    },
    heart: {
      loveStretchly: 'Love your Stretchly?',
      desc1: 'Taking regular breaks when using a computer is scientifically proven to be important for your physical and mental well-being.',
      desc2: 'Stretchly is free. But you can lend your support by donating and help us continue to improve Stretchly and release other free software.',
      becomePatron: 'Become a Patron',
      alreadyContributor: "I'm already a contributor",
      authenticateUsing: 'Authenticate using:',
      contributorPreferences: 'Contributor Preferences',
      syncPreferences: 'Sync Preferences'
    }
  },
  contributorPreferences: {
    '0': 'First monitor',
    '1': 'Second monitor',
    '2': 'Third monitor',
    '3': 'Fourth monitor',
    '4': 'Fifth monitor',
    title: 'Contributor Preferences',
    notifications: 'Break notifications:',
    notificationsInfo: 'System notification shown before breaks to let you prepare for it.',
    beforeLongBreak: 'Long Break:',
    beforeMiniBreak: 'Mini Break:',
    newVersion: 'New version:',
    newVersionNotification: 'Notify when new version is available',
    customIdeas: 'Custom ideas:',
    customIdeasInfo: 'Allows you to use custom break ideas by editing configuration file. (For advanced users.)',
    useIdeasFromSettings: 'Use break ideas from configuration file',
    breakPostpone: 'Postponement of breaks:',
    breakPostponeInfo: 'If enabled in main Preferences, you can postpone breaks. Following settings allow you to specify when, for how long and how many times you can postpone a break.',
    miniBreaks: 'Mini Breaks:',
    postponableFor: 'Postponable for:',
    postponeFor: 'Postpone for:',
    maxPostpones: 'Max of postpones:',
    longBreaks: 'Long Breaks:',
    pauseUntilMoring: 'Pause until morning:',
    pauseUntil: 'Pause until:',
    pauseUntilMorningInfo: "Specify till what hour 'Pause until morning' should pause.",
    welcomeWindow: 'Welcome window:',
    showWelcomeWindow: 'Show Welcome window on next start',
    opacityTheme: 'Theme transparency:',
    opacityInfo: 'How solid should the break window be?',
    opacity: 'Opacity:',
    breakWindowSize: 'Break window size',
    breakWindowSizeInfo: 'What percentage of the screen should the break window hide?',
    breakWindowWidth: 'Width:',
    breakWindowHeight: 'Height:',
    sounds: 'Sounds:',
    volume: 'Volume:',
    miniBreakStartSound: 'Play end-of-break sound also at the start of Mini break',
    longBreakStartSound: 'Play end-of-break sound also at the start of Long break',
    naturalBreaks: 'Natural breaks:',
    naturalBreaksInfo: 'If monitoring of idle time is enabled in main Preferences, you can specify after what time the breaks should be paused.',
    pauseAfter: 'Pause after:',
    appearance: 'Appearance:',
    light: 'Light',
    dark: 'Dark',
    system: 'System',
    showBreaksAsRegularWindowsTitle: 'Act as regular window:',
    showBreaksAsRegularWindowsInfo: "When enabled, Break windows will become focusable, they won't be 'Always on top' anymore and they will also appear in the taskbar.",
    showBreaksAsRegularWindows: 'Show breaks as regular windows',
    screen: 'Monitor for Breaks:',
    screenInfo: 'When showing breaks on all monitors is disabled, you can choose which one you would like to show your Breaks on.',
    showOnMonitor: 'Show Breaks on',
    primary: 'Primary monitor',
    cursor: 'Follow cursor',
    timeToBreakInTray: 'Time to break',
    showTimeToBreakInTray: 'Show time to the next break in menubar icon',
    showTrayIcon: 'Show menubar icon',
    toShowTrayIcon: 'Show Stretchly icon in menubar',
    currentTimeInBreaks: 'Current time',
    showCurrentTimeInBreaks: 'Show current local time in break window'
  },
  utils: {
    remaining: '{{count}} remaining',
    inAbout: 'in about {{count}}',
    none_one: '{{count}}',
    none_other: '{{count}}',
    percent_one: '{{count}} percent',
    percent_other: '{{count}} percent',
    oclock_one: "{{count}} o'clock",
    oclock_other: "{{count}} o'clock",
    seconds_one: '{{count}} second',
    seconds_other: '{{count}} seconds',
    minutes_one: '{{count}} minute',
    minutes_other: '{{count}} minutes',
    hours_one: '{{count}} hour',
    hours_other: '{{count}} hours'
  },
  process: { newVersionAvailable: 'New version is available!' },
  welcome: {
    title: 'Welcome to Stretchly',
    breakTimeReminderApp: 'The break time reminder app',
    viewTutorial: 'View Tutorial',
    openPreferences: 'Open Preferences',
    getStarted: 'Get Started'
  },
  statusMessages: {
    paused: 'Paused',
    indefinitely: 'Indefinitely',
    dndMode: 'Do Not Disturb is on',
    appExclusion: 'App exclusion rule',
    nextLongBreak: 'Next Long Break',
    nextMiniBreak: 'Next Mini Break',
    afterMiniBreak_one: 'after {{count}} Mini Break',
    afterMiniBreak_other: 'after {{count}} Mini Breaks',
    resuming: 'Resuming'
  },
  miniBreakIdeas: {
    aaa: { text: 'Go grab a glass of water.' },
    aab: { text: 'Slowly look all the way left, then right.' },
    aac: { text: 'Slowly look all the way up, then down.' },
    aad: { text: 'Close your eyes and take few deep breaths.' },
    aae: { text: 'Close your eyes and relax.' },
    aaf: { text: 'Stretch your legs.' },
    aag: { text: 'Stretch your arms.' },
    aah: { text: 'Is your sitting posture correct?' },
    aai: { text: 'Slowly turn head to side and hold for 10 seconds.' },
    aaj: { text: 'Slowly tilt head to side and hold for 5-10 seconds.' },
    aak: { text: 'Stand from your chair and stretch.' },
    aal: { text: 'Refocus your eyes on an object at least 20 meters away.' },
    aam: { text: 'Take a moment to think about something you appreciate.' },
    aan: { text: 'Take a moment to smile at being alive.' },
    aao: {
      text: 'A truly ergonomic workstation is one that you regularly push away from.'
    },
    aap: { text: 'Close your eyes and count your breaths.' },
    aaq: { text: 'Close your eyes and name the things you hear.' },
    aar: {
      text: 'Place your fingertips on your shoulders. Roll your shoulders forward for 10 seconds, then backward.'
    },
    aas: {
      text: 'Raise your right arm, stretch it over your head to the left, and hold for 10 seconds. Repeat on the other side.'
    },
    aat: {
      text: 'With your right hand, grab each finger of your left hand in turn and squeeze. Repeat on the other side.'
    },
    aau: {
      text: 'Stand up and do a lunge. Hold for 10 seconds, then do the other leg.'
    },
    aav: {
      text: 'Close your eyes and simply notice whatever arises in current moment, without judgement.'
    },
    aaw: {
      text: 'Focus every 20 minutes for 20 seconds on an object at 20 feet distance.'
    },
    aax: { text: 'If you need help, ask for it.' },
    aay: { text: 'Do one thing at a time.' },
    aaz: { text: 'Is your attention spent wisely?' },
    aba: { text: 'Change your sitting posture.' },
    abb: { text: 'Expose your eyes to natural light.' },
    abc: {
      text: 'With your eyes closed, slowly and gently raise your eyes to the ceiling and back down to the floor.'
    },
    abd: {
      text: 'With your eyes closed, slowly and gently move your eyes to the left, then slowly to the right.'
    },
    abe: { text: 'Shake your hands out to get some relief.' },
    abf: {
      text: 'One at a time, touch the tip of each finger to the tip of your thumb so they make an O-shape.'
    },
    abg: {
      text: "Make a fist and then slide your fingers up until they point toward the ceiling, like you're telling someone to stop."
    },
    abh: {
      text: 'Make a fist and then fan your fingers out and stretch them as far as you can.'
    },
    abi: {
      text: 'Sit tall, arms hanging at your sides, and slowly rotate neck in one direction in a large circle.'
    },
    abj: {
      text: 'Stand tall and slowly tilt your head toward the shoulder using the same hand until you feel a stretch.'
    },
    abk: {
      text: 'Stand tall with your arms by your side. Squeeze your shoulder blades together and hold.'
    },
    abl: {
      text: 'Stand tall with your arms raised along your shoulders. Move hands slightly behind your back, hold for a second and return.'
    },
    abm: {
      text: 'Sit on the edge of your chair, twist your torso to one side and hold for 10-15 seconds. Repeat on the other side.'
    },
    abn: {
      text: 'Stand up and put one foot on a nearby object, like a chair or step stool. Keep your knee bent and hold for 10-15 seconds. Repeatwith the other foot.'
    },
    abo: {
      text: 'Stand with your feet shoulder-width apart, lower your body down as if you were sitting back into a chair, then stand back up. Repeat several times.'
    },
    abp: {
      text: 'Stand with your back and hands on a wall, then slowly move your arms up and down as if you were making snow angels.'
    },
    abq: {
      text: 'Stand facing a wall and place your hands on it, then do several push-ups.'
    },
    abr: {
      text: 'Sit on the edge of your chair and extend one leg straight out in front of you, holding for 10-15 seconds. Repeat with the other leg.'
    },
    abs: {
      text: 'Stand facing a wall, put one foot back and the other foot forward, then lean into the wall. Repeat with the other leg.'
    },
    abt: {
      text: 'Hold one arm straight up, then use the other arm to gently push the elbow of the first arm towards your head. Hold for 10-15 seconds. Repeat with the other arm.'
    },
    abu: {
      text: 'Tilt your head to one side, then to the other side, and then gently tilt it forward and backward.'
    },
    abv: {
      text: 'Reach one arm across your chest, hold onto the elbow with the other hand, and gently pull it in towards your chest. Repeat with the other arm.'
    },
    abw: {
      text: 'Stand up, put one foot on a nearby object, like a chair or step stool, and reach down to touch your toes. Repeat with the other leg.'
    },
    abx: {
      text: 'Stand in a doorway and place one arm on each side of the doorway, then gently lean forward until you feel a stretch in your chest.'
    },
    aby: {
      text: 'Sit on the edge of a chair or on the floor, and place the soles of your feet together, gently pressing down with your elbows to stretch your inner thighs.'
    }
  },
  longBreakIdeas: {
    aaa: {
      title: 'Not alone',
      text: 'Do you find it hard to take a break alone? Try to do it with a co-worker. Aside from making it easier to stick to breaks, you will have a chance to get to know them better. Taking breaks together increases productivity.'
    },
    aab: {
      title: 'Step away',
      text: 'Do you ever notice how your brain can figure things out by itself? All it takes is to step away from the computer and take a break to think about something totally unrelated.'
    },
    aac: {
      title: 'Microbreaks',
      text: 'Rest is a key component in ensuring the performance of the musculoskeletal system. Frequent breaks can decrease the duration of a task and help lower the exposure to ergonomic injury risk.'
    },
    aad: {
      title: 'Meditation',
      text: 'Research studies suggest that mindfulness-based exercises help decrease anxiety, depression, stress, and pain, and help improve general health, mental health, and quality of life. Not sure how to start? There are numerous apps to help you out.'
    },
    aae: {
      title: 'Blink',
      text: 'Looking at screens for a long time causes you to blink less, thus exposing your eyes to the air. Blink rapidly for a few secondsto refresh the tear film and clear dust from the eye surface.'
    },
    aaf: {
      title: 'Ergonomics',
      text: 'Improper height and angle of the keyboard, mouse, monitor or working surface can cause health problems. Take some time to read about desk ergonomics.'
    },
    aag: {
      title: 'Move',
      text: 'There are a lot of ways you can exercise within your office. Try marching in place or doing desk push-ups.'
    },
    aah: {
      title: 'Change',
      text: 'Do you have a stability ball or standing work desk? Consider replacing your desk chair with them for a while.'
    },
    aai: {
      title: 'Notice',
      text: 'Are you daydreaming or having trouble focusing? It is a sign that you need to take a break.'
    },
    aaj: { title: 'Tech', text: 'How about taking a no-tech walk?' },
    aak: {
      title: 'Metabolism',
      text: 'Emerging research shows that sitting for long periods of time contributes to risk of metabolic syndrome, heart attack and strokerisk and overall death risk, among others. Taking regular walking breaks can help your circulation, working to counteract some of those problems.'
    },
    aal: {
      title: 'Active Meetings',
      text: 'How about moving meetings from the conference room to the concourse? Walking not only burns calories but it may even foster a sense of collaboration.'
    },
    aam: {
      title: 'Fruit',
      text: 'Take your time and eat some fruit. Slowly. Notice the flavor, the texture, the freshness.'
    },
    aan: {
      title: 'Bathrooms',
      text: 'Walk to the farthest bathroom in the worksite facility when going to the restroom.'
    },
    aao: {
      title: 'Coffee break',
      text: 'Going on coffee break? Consider doing a 5-minute walk every time you go for one.'
    },
    aap: {
      title: 'Colleagues',
      text: 'Do not email or message office colleagues, walk to their desks to communicate with them.'
    },
    aaq: {
      title: 'Learning',
      text: 'In a study of healthy volunteers, NIH researchers found that taking short breaks, early and often, may help our brains learn newskills.'
    },
    aar: {
      title: 'Exercise',
      text: 'Evidence suggests small amounts of regular exercise can bring dramatic health benefits, including measurably reducing stress.'
    },
    aas: {
      title: 'Repeat',
      text: 'Have you found your stretch-ly-routine? Do not forget to repeat it for more than once to better fight effects of prolonged sitting.'
    },
    aat: {
      title: 'Wrist and forearm',
      text: 'Extend your arms with the palms facing towards you, then slowly rotate the hands four times clockwise, then four times counter-clockwise.'
    },
    aau: {
      title: 'Back stretching',
      text: 'Join your hands behind your head, then lift them together up above your head ending with your palms facing upward.'
    },
    aav: {
      title: 'Mobilize',
      text: 'For every thirty minutes of stagnation, you should have at least one minute of stimulation.'
    },
    aaw: {
      title: '7 Minute Workout',
      text: 'This workout packs in a full-body exercise routine in a fraction of the time. But as with any exercise, be careful. There are numerous apps to get you started.'
    },
    aax: {
      title: 'Pulse',
      text: 'Raise your pulse rate to 120 beats per minute for 20 straight minutes four or five times a week doing anything you enjoy. Regularly raising your heart rate results in improved cardiovascular health.'
    },
    aay: {
      title: 'Take the stairs',
      text: 'Studies have shown that stair climbing, which is considered vigorous-intensity physical activity, burns more calories per minutethan jogging.'
    },
    aaz: {
      title: 'Make art',
      text: 'Art therapy is known to have great mental health benefits, especially when it comes to stress management. How about writing a quick poem, taking a picture or painting something small?'
    },
    aba: {
      title: 'Declutter',
      text: 'A clean space helps your focus at work and is often linked to positive emotions like happiness.'
    },
    abb: {
      title: 'Lunch outside',
      text: 'Nature is linked to positive emotions and decreased stress and anxiety. Whenever possible, try to take your daily lunch break outside, surrounded by some greenery.'
    },
    abc: {
      title: 'Public transport',
      text: 'If you use public transport regularly, you can stand instead of sitting. If it is possible, try to replace as many of your dailytrips as possible with walking or cycling.'
    },
    abd: {
      title: 'Yawning',
      text: 'Yawning can be really helpful, as it produces tears to help moisten and lubricate the eyes.'
    },
    abe: {
      title: 'Focus change',
      text: 'Hold one finger close to the eye and focus on it. Slowly move the finger away, focus far into the distance and then back to the finger. Bring the finger back and focus on something far away.'
    },
    abf: {
      title: 'Palming',
      text: 'While seated, brace elbows on the desk and close to the desk edge. Let your weight fall forward and cup hands over eyes. Close your eyes and inhale slowly through nose and hold for few seconds. Continue deep breathing.'
    },
    abg: {
      title: 'Hand squeezes',
      text: 'Squeeze a pair of balled-up socks or a soft rubber ball, hold for 5 seconds. Repeat whole process a few times.'
    },
    abh: {
      title: 'Slow Breathing',
      text: 'Emerging research suggests potential for use of controlled slow breathing techniques as a means of optimising physiological parameters that appear to be associated with health and longevity.'
    },
    abi: {
      title: 'Imaginative visualization',
      text: 'Close your eyes and imagine yourself in a peaceful and calming place, such as a beach or a forest, focusing on the sights, sounds, and sensations of that environment.'
    }
  }
}
12:33:48.228Stretchly: loading default break ideas
i18next: languageChanged en
i18next: initialized {
  debug: true,
  initImmediate: true,
  ns: [ 'translation' ],
  defaultNS: [ 'translation' ],
  fallbackLng: [ 'en' ],
  fallbackNS: false,
  supportedLngs: false,
  nonExplicitSupportedLngs: false,
  load: 'all',
  preload: false,
  simplifyPluralSuffix: true,
  keySeparator: '.',
  nsSeparator: ':',
  pluralSeparator: '_',
  contextSeparator: '_',
  partialBundledLanguages: false,
  saveMissing: false,
  updateMissing: false,
  saveMissingTo: 'fallback',
  saveMissingPlurals: true,
  missingKeyHandler: false,
  missingInterpolationHandler: false,
  postProcess: false,
  postProcessPassResolved: false,
  returnNull: false,
  returnEmptyString: true,
  returnObjects: false,
  joinArrays: false,
  returnedObjectHandler: false,
  parseMissingKeyHandler: false,
  appendNamespaceToMissingKey: false,
  appendNamespaceToCIMode: false,
  overloadTranslationOptionHandler: [Function: overloadTranslationOptionHandler],
  interpolation: {
    escapeValue: true,
    format: [Function: bound format],
    prefix: '{{',
    suffix: '}}',
    formatSeparator: ',',
    unescapePrefix: '-',
    nestingPrefix: '$t(',
    nestingSuffix: ')',
    nestingOptionsSeparator: ',',
    maxReplaces: 1000,
    skipOnVariables: true
  },
  lng: 'en',
  backend: {
    loadPath: '/Users/tobias/Development/repositories/github/stretchly/app/locales/{{lng}}.json',
    jsonIndent: 2,
    addPath: '/locales/{{lng}}/{{ns}}.missing.json',
    ident: 2,
    parse: [Function: parse],
    stringify: [Function: stringify]
  },
  ignoreJSONStructure: true
}
2024-11-23 12:33:48.441 Electron[60191:302529] +[IMKClient subclass]: chose IMKClient_Modern
2024-11-23 12:33:48.441 Electron[60191:302529] +[IMKInputSession subclass]: chose IMKInputSession_Modern
2024-11-23 12:33:49.012 Electron[60191:302529] MacosNotificationState: FocusStatusCenter API available
2024-11-23 12:33:49.052 Electron[60191:302529] MacosNotificationState: promise created
/Users/tobias/Development/repositories/github/stretchly/node_modules/electron/dist/Electron.app/Contents/MacOS/Electron exited with signal SIGABRT

@devtobi
Copy link
Author

devtobi commented Nov 23, 2024

I doubled checked whether the currently released version of Stretchly also has those issues but everything works fine and this time no crashes appear. So its really just a development thing.
Even after running npm run pack and then trying to launch the generated .app file, it crashes. Do you have any clue what might cause this? Or any clue on how could dive deeper into debugging this? As already mentioned npm run dev does not produce useful information.

@devtobi
Copy link
Author

devtobi commented Nov 23, 2024

I am using the current state of the trunk branch. Might this be an issue?

@hovancik
Copy link
Owner

I would try removing node_modules and running npm i -g npm to update npm and npm i again.

Trying on my mac machine and all works fine

@devtobi
Copy link
Author

devtobi commented Nov 23, 2024

Already did that. Unfortunately it is still not working. 😟

@hovancik
Copy link
Owner

Uf, at loss here. Maybe try running example electron app if that works?

https://github.com/electron/electron-quick-start

@devtobi
Copy link
Author

devtobi commented Nov 24, 2024

The electron example app works without any issues. I have a strong assumption it might be because Stretchly might be using the FocusStatusCenter API in electron and some kind of permissions missing. @hovancik Does Stretchly make use of this API inside its code?
See e.g. this comment ferdium/ferdium-app#1892 (comment) where someone reports crash issues when electron tries to access the focus status of the OS. Could this be the same cause?

I checked the Info.plist files and did not find NSFocusStatusUsageDescription there. However in the currently released version the key is not included there either so this might also not be the reason.

I even tried including the crashHandler of electron to get more debug output but this didn't help as well.
As far as I researched this SIGABRT errors in macOS often happen due to missing of certain usage descriptions.

@hovancik Can you confirm that you get

[20722:1125/000228.482909:WARNING:viz_main_impl.cc(85)] VizNullHypothesis is disabled (not a warning)
i18next: hasLoadedNamespace: i18next was not initialized undefined
i18next::translator: key "miniBreakIdeas" for languages "en" won't get resolved as namespace "translation" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!

as well when starting the app in development mode using the current trunk? This way I can exclude one more thing from the causes.

For some reason using npm run pack now produces an app that I can run without crashes. Not the most elegant solution for developing but might be a temporary solution.

@hovancik
Copy link
Owner

This is my output:

➜  stretchly git:(trunk) npm run dev

> [email protected] dev
> cross-env NODE_ENV=development electron . --trace-warnings --trace-deprecation --enable-logging --remote-debugging-port=9222


DevTools listening on ws://127.0.0.1:9222/devtools/browser/24b22217-aab7-4be6-a094-0299d5e9a04d
19:29:50.683 › Stretchly: initializing...
19:29:50.709 › Stretchly: loading preferences
19:29:50.726 › Stretchly: starting Idle time monitoring
i18next: hasLoadedNamespace: i18next was not initialized undefined
i18next::translator: key "miniBreakIdeas" for languages "en" won't get resolved as namespace "translation" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!
i18next::translator: missingKey en translation miniBreakIdeas miniBreakIdeas
i18next::translator: missingKey undefined translation miniBreakIdeas.0.text miniBreakIdeas.0.text
i18next::translator: missingKey undefined translation miniBreakIdeas.1.text miniBreakIdeas.1.text
i18next::translator: missingKey undefined translation miniBreakIdeas.2.text miniBreakIdeas.2.text
i18next::translator: missingKey undefined translation miniBreakIdeas.3.text miniBreakIdeas.3.text
i18next::translator: missingKey undefined translation miniBreakIdeas.4.text miniBreakIdeas.4.text
i18next::translator: missingKey undefined translation miniBreakIdeas.5.text miniBreakIdeas.5.text
i18next::translator: missingKey undefined translation miniBreakIdeas.6.text miniBreakIdeas.6.text
i18next::translator: missingKey undefined translation miniBreakIdeas.7.text miniBreakIdeas.7.text
i18next::translator: missingKey undefined translation miniBreakIdeas.8.text miniBreakIdeas.8.text
i18next::translator: missingKey undefined translation miniBreakIdeas.9.text miniBreakIdeas.9.text
i18next::translator: missingKey undefined translation miniBreakIdeas.10.text miniBreakIdeas.10.text
i18next::translator: missingKey undefined translation miniBreakIdeas.11.text miniBreakIdeas.11.text
i18next::translator: missingKey undefined translation miniBreakIdeas.12.text miniBreakIdeas.12.text
i18next::translator: missingKey undefined translation miniBreakIdeas.13.text miniBreakIdeas.13.text
i18next::translator: missingKey en translation longBreakIdeas longBreakIdeas
i18next::translator: missingKey undefined translation longBreakIdeas.0.title longBreakIdeas.0.title
i18next::translator: missingKey undefined translation longBreakIdeas.0.text longBreakIdeas.0.text
i18next::translator: missingKey undefined translation longBreakIdeas.1.title longBreakIdeas.1.title
i18next::translator: missingKey undefined translation longBreakIdeas.1.text longBreakIdeas.1.text
i18next::translator: missingKey undefined translation longBreakIdeas.2.title longBreakIdeas.2.title
i18next::translator: missingKey undefined translation longBreakIdeas.2.text longBreakIdeas.2.text
i18next::translator: missingKey undefined translation longBreakIdeas.3.title longBreakIdeas.3.title
i18next::translator: missingKey undefined translation longBreakIdeas.3.text longBreakIdeas.3.text
i18next::translator: missingKey undefined translation longBreakIdeas.4.title longBreakIdeas.4.title
i18next::translator: missingKey undefined translation longBreakIdeas.4.text longBreakIdeas.4.text
i18next::translator: missingKey undefined translation longBreakIdeas.5.title longBreakIdeas.5.title
i18next::translator: missingKey undefined translation longBreakIdeas.5.text longBreakIdeas.5.text
i18next::translator: missingKey undefined translation longBreakIdeas.6.title longBreakIdeas.6.title
i18next::translator: missingKey undefined translation longBreakIdeas.6.text longBreakIdeas.6.text
i18next::translator: missingKey undefined translation longBreakIdeas.7.title longBreakIdeas.7.title
i18next::translator: missingKey undefined translation longBreakIdeas.7.text longBreakIdeas.7.text
i18next::translator: missingKey undefined translation longBreakIdeas.8.title longBreakIdeas.8.title
i18next::translator: missingKey undefined translation longBreakIdeas.8.text longBreakIdeas.8.text
i18next::translator: missingKey undefined translation longBreakIdeas.9.title longBreakIdeas.9.title
i18next::translator: missingKey undefined translation longBreakIdeas.9.text longBreakIdeas.9.text
i18next::translator: missingKey undefined translation longBreakIdeas.10.title longBreakIdeas.10.title
i18next::translator: missingKey undefined translation longBreakIdeas.10.text longBreakIdeas.10.text
i18next::translator: missingKey undefined translation longBreakIdeas.11.title longBreakIdeas.11.title
i18next::translator: missingKey undefined translation longBreakIdeas.11.text longBreakIdeas.11.text
i18next::translator: missingKey undefined translation longBreakIdeas.12.title longBreakIdeas.12.title
i18next::translator: missingKey undefined translation longBreakIdeas.12.text longBreakIdeas.12.text
i18next::translator: missingKey undefined translation longBreakIdeas.13.title longBreakIdeas.13.title
i18next::translator: missingKey undefined translation longBreakIdeas.13.text longBreakIdeas.13.text
19:29:51.091 › Stretchly: loading default break ideas
i18next::translator: missingKey undefined translation main.toolTipHeader main.toolTipHeader
i18next::translator: missingKey undefined translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey undefined translation utils.inAbout utils.inAbout
i18next::translator: missingKey undefined translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey undefined translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey undefined translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey undefined translation utils.inAbout utils.inAbout
i18next::translator: missingKey undefined translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey undefined translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey undefined translation main.toMicrobreak main.toMicrobreak
i18next::translator: missingKey undefined translation main.toBreak main.toBreak
i18next::translator: missingKey undefined translation main.skipToTheNext main.skipToTheNext
i18next::translator: missingKey undefined translation main.pause main.pause
i18next::translator: missingKey undefined translation utils.minutes utils.minutes
i18next::translator: missingKey undefined translation main.forHour main.forHour
i18next::translator: missingKey undefined translation main.for2Hours main.for2Hours
i18next::translator: missingKey undefined translation main.for5Hours main.for5Hours
i18next::translator: missingKey undefined translation main.untilMorning main.untilMorning
i18next::translator: missingKey undefined translation main.indefinitely main.indefinitely
i18next::translator: missingKey undefined translation main.resetBreaks main.resetBreaks
i18next::translator: missingKey undefined translation main.preferences main.preferences
i18next::translator: missingKey undefined translation main.quitStretchly main.quitStretchly
i18next::translator: missingKey en translation main.toolTipHeader main.toolTipHeader
i18next::translator: missingKey en translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey en translation utils.inAbout utils.inAbout
i18next::translator: missingKey en translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey en translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey en translation statusMessages.nextMiniBreak statusMessages.nextMiniBreak
i18next::translator: missingKey en translation utils.inAbout utils.inAbout
i18next::translator: missingKey en translation statusMessages.nextLongBreak statusMessages.nextLongBreak
i18next::translator: missingKey en translation statusMessages.afterMiniBreak statusMessages.afterMiniBreak
i18next::translator: missingKey en translation main.toMicrobreak main.toMicrobreak
i18next::translator: missingKey en translation main.toBreak main.toBreak
i18next::translator: missingKey en translation main.skipToTheNext main.skipToTheNext
i18next::translator: missingKey en translation main.pause main.pause
i18next::translator: missingKey en translation utils.minutes utils.minutes
i18next::translator: missingKey en translation main.forHour main.forHour
i18next::translator: missingKey en translation main.for2Hours main.for2Hours
i18next::translator: missingKey en translation main.for5Hours main.for5Hours
i18next::translator: missingKey en translation main.untilMorning main.untilMorning
i18next::translator: missingKey en translation main.indefinitely main.indefinitely
i18next::translator: missingKey en translation main.resetBreaks main.resetBreaks
i18next::translator: missingKey en translation main.preferences main.preferences
i18next::translator: missingKey en translation main.quitStretchly main.quitStretchly
i18next::backendConnector: loaded namespace translation for language en {
  main: {
    toolTipHeader: 'Stretchly - The break time reminder app',
    microbreakIn: "Mini Break in $t(utils.seconds, {'count': {{seconds}} })",
    breakIn: "Long Break in $t(utils.seconds, {'count': {{seconds}} })",
    resumingBreaks: 'Resuming breaks',
    downloadLatestVersion: 'Download latest version',
    toBreak: 'Long Break',
    toMicrobreak: 'Mini Break',
    skipToTheNext: 'Skip to the next',
    resume: 'Resume Breaks',
    pause: 'Pause Breaks',
    forHour: '1 hour',
    for2Hours: '2 hours',
    for5Hours: '5 hours',
    untilMorning: 'Until morning',
    indefinitely: 'Indefinitely',
    resetBreaks: 'Reset Breaks',
    quitStretchly: 'Quit Stretchly',
    restoreDefaults: 'Restore defaults',
    warning: 'This will restore app defaults and all your settings will be lost.',
    continue: 'Continue',
    cancel: 'Cancel',
    preferences: 'Preferences',
    contributorPreferences: 'Contributor Preferences',
    syncPreferences: 'Sync Preferences'
  },
  break: {
    postpone: 'Postpone this break',
    skip: 'Skip this break',
    title: 'Time to take a break!'
  },
  preferences: {
    title: 'Stretchly Preferences',
    nav: {
      settings: 'Settings',
      schedule: 'Schedule',
      theme: 'Theme',
      about: 'About',
      heart: 'Love Stretchly'
    },
    settings: {
      openAtLogin: 'Start Stretchly automatically when logging in',
      showBreaksIn: 'Shows breaks in:',
      window: 'Window',
      fullscreen: 'Full screen',
      showIdeas: 'Show exercise tips during breaks',
      allScreens: 'Shows breaks on all monitors',
      monitorIdleTime: 'Monitor system idle time (breaks are paused if system is idle).',
      monitorDnd: 'Show breaks even in Do Not Disturb mode',
      language: 'Select language:',
      restoreDefaults: 'Restore defaults'
    },
    schedule: {
      miniBreaks: 'Mini Breaks:',
      miniBreaksInfo: 'Mini Breaks are short breaks taken regularly to give you a chance to stretch and relax.',
      enableMiniBreaks: 'Enable Mini Breaks',
      breakFor: 'Break for:',
      every: 'Every:',
      showNotificationBeforeMiniBreak: 'Show notification before Mini Break starts',
      enablePostponeMini: 'Enable Postponement for Mini Break',
      longBreaks: 'Long Breaks:',
      longBreaksInfo: 'Long Breaks are taken less regularly, but are of greater duration, allowing you to take an extended break from your work.',
      enableLongBreaks: 'Enable Long Breaks',
      showNotificationBeforeLongBreak: 'Show notification before Long Break starts',
      enablePostponeLong: 'Enable Postponement for Long Break',
      strictMode: 'Strict Mode:',
      strictModeInfo: 'Strict Mode prevents you from skipping either Mini Breaks or Long Breaks and is designed to help discipline.',
      enableStrictMini: 'Enable Strict Mode for Mini Breaks',
      enableStrictLong: 'Enable Strict Mode for Long Breaks',
      cantDisableBoth: 'It is not possible to disable both types of breaks'
    },
    theme: {
      appearance: 'Appearance:',
      greenClouds: 'Green clouds',
      autumnBeBlessed: 'Autumn be blessed',
      graphiteCrystal: 'Graphite crystal',
      coffeeKisses: 'Coffee kisses',
      morningSwim: 'Morning swim',
      transparentMode: 'Enable transparency',
      sounds: 'Sounds:',
      enableSounds: 'Enable sounds',
      crystalGlass: 'Crystal glass',
      windChime: 'Wind chime',
      ticToc: 'Tic toc',
      reverie: 'Reverie',
      menubarIcon: 'Menubar icon:',
      colour: 'Colour',
      monochrome: 'Monochrome',
      invertedMonochrome: 'Inverted Monochrome',
      snowWhite: 'Snow white'
    },
    about: {
      tagline: 'The break time reminder app',
      version: 'Version ',
      latestVersion: 'Latest version ',
      checkNewVersion: 'Automatically check for app updates',
      learnMore: 'To learn more about Stretchly features, view a tutorial, download the latest version or contact us for support, ',
      ourWebsite: 'visit our website',
      dot: '.',
      developedBy: 'Developed by',
      janH: 'Jan Hovancik',
      designedBy: 'Icon and UI design by Colin Shanley'
    },
    heart: {
      loveStretchly: 'Love your Stretchly?',
      desc1: 'Taking regular breaks when using a computer is scientifically proven to be important for your physical and mental well-being.',
      desc2: 'Stretchly is free. But you can lend your support by donating and help us continue to improve Stretchly and release other free software.',
      becomePatron: 'Become a Patron',
      alreadyContributor: "I'm already a contributor",
      authenticateUsing: 'Authenticate using:',
      contributorPreferences: 'Contributor Preferences',
      syncPreferences: 'Sync Preferences'
    }
  },
  contributorPreferences: {
    '0': 'First monitor',
    '1': 'Second monitor',
    '2': 'Third monitor',
    '3': 'Fourth monitor',
    '4': 'Fifth monitor',
    title: 'Contributor Preferences',
    notifications: 'Break notifications:',
    notificationsInfo: 'System notification shown before breaks to let you prepare for it.',
    beforeLongBreak: 'Long Break:',
    beforeMiniBreak: 'Mini Break:',
    newVersion: 'New version:',
    newVersionNotification: 'Notify when new version is available',
    customIdeas: 'Custom ideas:',
    customIdeasInfo: 'Allows you to use custom break ideas by editing configuration file. (For advanced users.)',
    useIdeasFromSettings: 'Use break ideas from configuration file',
    breakPostpone: 'Postponement of breaks:',
    breakPostponeInfo: 'If enabled in main Preferences, you can postpone breaks. Following settings allow you to specify when, for how long and how many times you can postpone a break.',
    miniBreaks: 'Mini Breaks:',
    postponableFor: 'Postponable for:',
    postponeFor: 'Postpone for:',
    maxPostpones: 'Max of postpones:',
    longBreaks: 'Long Breaks:',
    pauseUntilMoring: 'Pause until morning:',
    pauseUntil: 'Pause until:',
    pauseUntilMorningInfo: "Specify till what hour 'Pause until morning' should pause.",
    welcomeWindow: 'Welcome window:',
    showWelcomeWindow: 'Show Welcome window on next start',
    opacityTheme: 'Theme transparency:',
    opacityInfo: 'How solid should the break window be?',
    opacity: 'Opacity:',
    breakWindowSize: 'Break window size',
    breakWindowSizeInfo: 'What percentage of the screen should the break window hide?',
    breakWindowWidth: 'Width:',
    breakWindowHeight: 'Height:',
    sounds: 'Sounds:',
    volume: 'Volume:',
    miniBreakStartSound: 'Play end-of-break sound also at the start of Mini break',
    longBreakStartSound: 'Play end-of-break sound also at the start of Long break',
    naturalBreaks: 'Natural breaks:',
    naturalBreaksInfo: 'If monitoring of idle time is enabled in main Preferences, you can specify after what time the breaks should be paused.',
    pauseAfter: 'Pause after:',
    appearance: 'Appearance:',
    light: 'Light',
    dark: 'Dark',
    system: 'System',
    showBreaksAsRegularWindowsTitle: 'Act as regular window:',
    showBreaksAsRegularWindowsInfo: "When enabled, Break windows will become focusable, they won't be 'Always on top' anymore and they will also appear in the taskbar.",
    showBreaksAsRegularWindows: 'Show breaks as regular windows',
    screen: 'Monitor for Breaks:',
    screenInfo: 'When showing breaks on all monitors is disabled, you can choose which one you would like to show your Breaks on.',
    showOnMonitor: 'Show Breaks on',
    primary: 'Primary monitor',
    cursor: 'Follow cursor',
    timeToBreakInTray: 'Time to break',
    showTimeToBreakInTray: 'Show time to the next break in menubar icon',
    showTrayIcon: 'Show menubar icon',
    toShowTrayIcon: 'Show Stretchly icon in menubar',
    currentTimeInBreaks: 'Current time',
    showCurrentTimeInBreaks: 'Show current local time in break window'
  },
  utils: {
    remaining: '{{count}} remaining',
    inAbout: 'in about {{count}}',
    none_one: '{{count}}',
    none_other: '{{count}}',
    percent_one: '{{count}} percent',
    percent_other: '{{count}} percent',
    oclock_one: "{{count}} o'clock",
    oclock_other: "{{count}} o'clock",
    seconds_one: '{{count}} second',
    seconds_other: '{{count}} seconds',
    minutes_one: '{{count}} minute',
    minutes_other: '{{count}} minutes',
    hours_one: '{{count}} hour',
    hours_other: '{{count}} hours'
  },
  process: { newVersionAvailable: 'New version is available!' },
  welcome: {
    title: 'Welcome to Stretchly',
    breakTimeReminderApp: 'The break time reminder app',
    viewTutorial: 'View Tutorial',
    openPreferences: 'Open Preferences',
    getStarted: 'Get Started'
  },
  statusMessages: {
    paused: 'Paused',
    indefinitely: 'Indefinitely',
    dndMode: 'Do Not Disturb is on',
    appExclusion: 'App exclusion rule',
    nextLongBreak: 'Next Long Break',
    nextMiniBreak: 'Next Mini Break',
    afterMiniBreak_one: 'after {{count}} Mini Break',
    afterMiniBreak_other: 'after {{count}} Mini Breaks',
    resuming: 'Resuming'
  },
  miniBreakIdeas: {
    aaa: { text: 'Go grab a glass of water.' },
    aab: { text: 'Slowly look all the way left, then right.' },
    aac: { text: 'Slowly look all the way up, then down.' },
    aad: { text: 'Close your eyes and take few deep breaths.' },
    aae: { text: 'Close your eyes and relax.' },
    aaf: { text: 'Stretch your legs.' },
    aag: { text: 'Stretch your arms.' },
    aah: { text: 'Is your sitting posture correct?' },
    aai: { text: 'Slowly turn head to side and hold for 10 seconds.' },
    aaj: { text: 'Slowly tilt head to side and hold for 5-10 seconds.' },
    aak: { text: 'Stand from your chair and stretch.' },
    aal: { text: 'Refocus your eyes on an object at least 20 meters away.' },
    aam: { text: 'Take a moment to think about something you appreciate.' },
    aan: { text: 'Take a moment to smile at being alive.' },
    aao: {
      text: 'A truly ergonomic workstation is one that you regularly push away from.'
    },
    aap: { text: 'Close your eyes and count your breaths.' },
    aaq: { text: 'Close your eyes and name the things you hear.' },
    aar: {
      text: 'Place your fingertips on your shoulders. Roll your shoulders forward for 10 seconds, then backward.'
    },
    aas: {
      text: 'Raise your right arm, stretch it over your head to the left, and hold for 10 seconds. Repeat on the other side.'
    },
    aat: {
      text: 'With your right hand, grab each finger of your left hand in turn and squeeze. Repeat on the other side.'
    },
    aau: {
      text: 'Stand up and do a lunge. Hold for 10 seconds, then do the other leg.'
    },
    aav: {
      text: 'Close your eyes and simply notice whatever arises in current moment, without judgement.'
    },
    aaw: {
      text: 'Focus every 20 minutes for 20 seconds on an object at 20 feet distance.'
    },
    aax: { text: 'If you need help, ask for it.' },
    aay: { text: 'Do one thing at a time.' },
    aaz: { text: 'Is your attention spent wisely?' },
    aba: { text: 'Change your sitting posture.' },
    abb: { text: 'Expose your eyes to natural light.' },
    abc: {
      text: 'With your eyes closed, slowly and gently raise your eyes to the ceiling and back down to the floor.'
    },
    abd: {
      text: 'With your eyes closed, slowly and gently move your eyes to the left, then slowly to the right.'
    },
    abe: { text: 'Shake your hands out to get some relief.' },
    abf: {
      text: 'One at a time, touch the tip of each finger to the tip of your thumb so they make an O-shape.'
    },
    abg: {
      text: "Make a fist and then slide your fingers up until they point toward the ceiling, like you're telling someone to stop."
    },
    abh: {
      text: 'Make a fist and then fan your fingers out and stretch them as far as you can.'
    },
    abi: {
      text: 'Sit tall, arms hanging at your sides, and slowly rotate neck in one direction in a large circle.'
    },
    abj: {
      text: 'Stand tall and slowly tilt your head toward the shoulder using the same hand until you feel a stretch.'
    },
    abk: {
      text: 'Stand tall with your arms by your side. Squeeze your shoulder blades together and hold.'
    },
    abl: {
      text: 'Stand tall with your arms raised along your shoulders. Move hands slightly behind your back, hold for a second and return.'
    },
    abm: {
      text: 'Sit on the edge of your chair, twist your torso to one side and hold for 10-15 seconds. Repeat on the other side.'
    },
    abn: {
      text: 'Stand up and put one foot on a nearby object, like a chair or step stool. Keep your knee bent and hold for 10-15 seconds. Repeat with the other foot.'
    },
    abo: {
      text: 'Stand with your feet shoulder-width apart, lower your body down as if you were sitting back into a chair, then stand back up. Repeat several times.'
    },
    abp: {
      text: 'Stand with your back and hands on a wall, then slowly move your arms up and down as if you were making snow angels.'
    },
    abq: {
      text: 'Stand facing a wall and place your hands on it, then do several push-ups.'
    },
    abr: {
      text: 'Sit on the edge of your chair and extend one leg straight out in front of you, holding for 10-15 seconds. Repeat with the other leg.'
    },
    abs: {
      text: 'Stand facing a wall, put one foot back and the other foot forward, then lean into the wall. Repeat with the other leg.'
    },
    abt: {
      text: 'Hold one arm straight up, then use the other arm to gently push the elbow of the first arm towards your head. Hold for 10-15 seconds. Repeat with the other arm.'
    },
    abu: {
      text: 'Tilt your head to one side, then to the other side, and then gently tilt it forward and backward.'
    },
    abv: {
      text: 'Reach one arm across your chest, hold onto the elbow with the other hand, and gently pull it in towards your chest. Repeat with the other arm.'
    },
    abw: {
      text: 'Stand up, put one foot on a nearby object, like a chair or step stool, and reach down to touch your toes. Repeat with the other leg.'
    },
    abx: {
      text: 'Stand in a doorway and place one arm on each side of the doorway, then gently lean forward until you feel a stretch in your chest.'
    },
    aby: {
      text: 'Sit on the edge of a chair or on the floor, and place the soles of your feet together, gently pressing down with your elbows to stretch your inner thighs.'
    }
  },
  longBreakIdeas: {
    aaa: {
      title: 'Not alone',
      text: 'Do you find it hard to take a break alone? Try to do it with a co-worker. Aside from making it easier to stick to breaks, you will have a chance to get to know them better. Taking breaks together increases productivity.'
    },
    aab: {
      title: 'Step away',
      text: 'Do you ever notice how your brain can figure things out by itself? All it takes is to step away from the computer and take a break to think about something totally unrelated.'
    },
    aac: {
      title: 'Microbreaks',
      text: 'Rest is a key component in ensuring the performance of the musculoskeletal system. Frequent breaks can decrease the duration of a task and help lower the exposure to ergonomic injury risk.'
    },
    aad: {
      title: 'Meditation',
      text: 'Research studies suggest that mindfulness-based exercises help decrease anxiety, depression, stress, and pain, and help improve general health, mental health, and quality of life. Not sure how to start? There are numerous apps to help you out.'
    },
    aae: {
      title: 'Blink',
      text: 'Looking at screens for a long time causes you to blink less, thus exposing your eyes to the air. Blink rapidly for a few seconds to refresh the tear film and clear dust from the eye surface.'
    },
    aaf: {
      title: 'Ergonomics',
      text: 'Improper height and angle of the keyboard, mouse, monitor or working surface can cause health problems. Take some time to read about desk ergonomics.'
    },
    aag: {
      title: 'Move',
      text: 'There are a lot of ways you can exercise within your office. Try marching in place or doing desk push-ups.'
    },
    aah: {
      title: 'Change',
      text: 'Do you have a stability ball or standing work desk? Consider replacing your desk chair with them for a while.'
    },
    aai: {
      title: 'Notice',
      text: 'Are you daydreaming or having trouble focusing? It is a sign that you need to take a break.'
    },
    aaj: { title: 'Tech', text: 'How about taking a no-tech walk?' },
    aak: {
      title: 'Metabolism',
      text: 'Emerging research shows that sitting for long periods of time contributes to risk of metabolic syndrome, heart attack and stroke risk and overall death risk, among others. Taking regular walking breaks can help your circulation, working to counteract some of those problems.'
    },
    aal: {
      title: 'Active Meetings',
      text: 'How about moving meetings from the conference room to the concourse? Walking not only burns calories but it may even foster a sense of collaboration.'
    },
    aam: {
      title: 'Fruit',
      text: 'Take your time and eat some fruit. Slowly. Notice the flavor, the texture, the freshness.'
    },
    aan: {
      title: 'Bathrooms',
      text: 'Walk to the farthest bathroom in the worksite facility when going to the restroom.'
    },
    aao: {
      title: 'Coffee break',
      text: 'Going on coffee break? Consider doing a 5-minute walk every time you go for one.'
    },
    aap: {
      title: 'Colleagues',
      text: 'Do not email or message office colleagues, walk to their desks to communicate with them.'
    },
    aaq: {
      title: 'Learning',
      text: 'In a study of healthy volunteers, NIH researchers found that taking short breaks, early and often, may help our brains learn new skills.'
    },
    aar: {
      title: 'Exercise',
      text: 'Evidence suggests small amounts of regular exercise can bring dramatic health benefits, including measurably reducing stress.'
    },
    aas: {
      title: 'Repeat',
      text: 'Have you found your stretch-ly-routine? Do not forget to repeat it for more than once to better fight effects of prolonged sitting.'
    },
    aat: {
      title: 'Wrist and forearm',
      text: 'Extend your arms with the palms facing towards you, then slowly rotate the hands four times clockwise, then four times counter-clockwise.'
    },
    aau: {
      title: 'Back stretching',
      text: 'Join your hands behind your head, then lift them together up above your head ending with your palms facing upward.'
    },
    aav: {
      title: 'Mobilize',
      text: 'For every thirty minutes of stagnation, you should have at least one minute of stimulation.'
    },
    aaw: {
      title: '7 Minute Workout',
      text: 'This workout packs in a full-body exercise routine in a fraction of the time. But as with any exercise, be careful. There are numerous apps to get you started.'
    },
    aax: {
      title: 'Pulse',
      text: 'Raise your pulse rate to 120 beats per minute for 20 straight minutes four or five times a week doing anything you enjoy. Regularly raising your heart rate results in improved cardiovascular health.'
    },
    aay: {
      title: 'Take the stairs',
      text: 'Studies have shown that stair climbing, which is considered vigorous-intensity physical activity, burns more calories per minute than jogging.'
    },
    aaz: {
      title: 'Make art',
      text: 'Art therapy is known to have great mental health benefits, especially when it comes to stress management. How about writing a quick poem, taking a picture or painting something small?'
    },
    aba: {
      title: 'Declutter',
      text: 'A clean space helps your focus at work and is often linked to positive emotions like happiness.'
    },
    abb: {
      title: 'Lunch outside',
      text: 'Nature is linked to positive emotions and decreased stress and anxiety. Whenever possible, try to take your daily lunch break outside, surrounded by some greenery.'
    },
    abc: {
      title: 'Public transport',
      text: 'If you use public transport regularly, you can stand instead of sitting. If it is possible, try to replace as many of your daily trips as possible with walking or cycling.'
    },
    abd: {
      title: 'Yawning',
      text: 'Yawning can be really helpful, as it produces tears to help moisten and lubricate the eyes.'
    },
    abe: {
      title: 'Focus change',
      text: 'Hold one finger close to the eye and focus on it. Slowly move the finger away, focus far into the distance and then back to the finger. Bring the finger back and focus on something far away.'
    },
    abf: {
      title: 'Palming',
      text: 'While seated, brace elbows on the desk and close to the desk edge. Let your weight fall forward and cup hands over eyes. Close your eyes and inhale slowly through nose and hold for few seconds. Continue deep breathing.'
    },
    abg: {
      title: 'Hand squeezes',
      text: 'Squeeze a pair of balled-up socks or a soft rubber ball, hold for 5 seconds. Repeat whole process a few times.'
    },
    abh: {
      title: 'Slow Breathing',
      text: 'Emerging research suggests potential for use of controlled slow breathing techniques as a means of optimising physiological parameters that appear to be associated with health and longevity.'
    },
    abi: {
      title: 'Imaginative visualization',
      text: 'Close your eyes and imagine yourself in a peaceful and calming place, such as a beach or a forest, focusing on the sights, sounds, and sensations of that environment.'
    }
  }
}
19:29:51.750 › Stretchly: loading default break ideas
i18next: languageChanged en
i18next: initialized {
  debug: true,
  initImmediate: true,
  ns: [ 'translation' ],
  defaultNS: [ 'translation' ],
  fallbackLng: [ 'en' ],
  fallbackNS: false,
  supportedLngs: false,
  nonExplicitSupportedLngs: false,
  load: 'all',
  preload: false,
  simplifyPluralSuffix: true,
  keySeparator: '.',
  nsSeparator: ':',
  pluralSeparator: '_',
  contextSeparator: '_',
  partialBundledLanguages: false,
  saveMissing: false,
  updateMissing: false,
  saveMissingTo: 'fallback',
  saveMissingPlurals: true,
  missingKeyHandler: false,
  missingInterpolationHandler: false,
  postProcess: false,
  postProcessPassResolved: false,
  returnNull: false,
  returnEmptyString: true,
  returnObjects: false,
  joinArrays: false,
  returnedObjectHandler: false,
  parseMissingKeyHandler: false,
  appendNamespaceToMissingKey: false,
  appendNamespaceToCIMode: false,
  overloadTranslationOptionHandler: [Function: overloadTranslationOptionHandler],
  interpolation: {
    escapeValue: true,
    format: [Function: bound format],
    prefix: '{{',
    suffix: '}}',
    formatSeparator: ',',
    unescapePrefix: '-',
    nestingPrefix: '$t(',
    nestingSuffix: ')',
    nestingOptionsSeparator: ',',
    maxReplaces: 1000,
    skipOnVariables: true
  },
  lng: 'en',
  backend: {
    loadPath: '/Users/conta/workspace/hovancik/stretchly/app/locales/{{lng}}.json',
    jsonIndent: 2,
    addPath: '/locales/{{lng}}/{{ns}}.missing.json',
    ident: 2,
    parse: [Function: parse],
    stringify: [Function: stringify]
  },
  ignoreJSONStructure: true
}
[1252:1125/192951.917725:WARNING:viz_main_impl.cc(85)] VizNullHypothesis is disabled (not a warning)
19:29:53.117 › Stretchly: checking for new version (local: v1.16.0, remote: 1.16.0)

@hovancik
Copy link
Owner

Not sure what is FocusStatus thingy, I use package macos-notification-state but not sure if that even works. I have not been using mac for years

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants