Skip to content

Instantly share code, notes, and snippets.

@HoussemNasri
Last active May 18, 2024 15:01
Show Gist options
  • Save HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28 to your computer and use it in GitHub Desktop.
Save HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28 to your computer and use it in GitHub Desktop.
Extend your trial period for Balsamiq Wireframes on Windows and macOS Forever!

Overview

This script will prolong your trial time for Balsamiq Wireframes on both Windows and macOS. You may also manually apply the hack by following the steps in Manual Editing.

Prerequisites

  • python3

⚠️ Warning: Close all balsamiq wireframes instances before proceeding, otherwise the operation won't succeed.

Run the script

⚠️ Works only on Windows, for MacOS check the Manual Editing section.

  1. Download and install python3
  2. Download the script and extract it
  3. Open the terminal and navigate to the script location
  4. Close Balsamiq
  5. Run python BalsamiqForever.py or python3 BalsamiqForever.py

Manual Editing

If running the script didn't do it or you just want to get your hands dirty, here is how to apply the hack manualy by editing configuration files on the application folder.

Windows

  1. Open this file in your text editor %APPDATA%\Balsamiq\Balsamiq Wireframes\LocalSettings.json.
  2. Edit DefaultSelectionColorRGBA property and increase it's value.

For example, if you're using this configuration "DefaultSelectionColorRGBA": 1916130510, your trial will expire in September 20, 2030 🤯, for custom expiration date use this website.

  1. Save changes.

MacOS

Adding support for macOS wouldn't be possible without the help of @pep108 and @megatunger.

  1. Open this file in your text editor /Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js.
  2. Search for this function function getLicenseValidFromLicenseData(data).
  3. Replce function body by return true.
//result
function getLicenseValidFromLicenseData(data) {
      return true
}
  1. Save.
import json
import os
import time
import webbrowser
import sys
import re
def handleWindows(extra_seconds):
print("OS : Windows")
local_settings = r"{}\Balsamiq\Balsamiq Wireframes\LocalSettings.json".format(os.getenv('APPDATA'))
print("Reading from {}".format(local_settings))
with open(local_settings) as reader:
json_data = json.load(reader)
json_data['DefaultSelectionColorRGBA'] = int(time.time()) + extra_seconds
print("Writing to {}".format(local_settings))
with open(local_settings, 'w') as outfile:
json.dump(json_data, outfile)
def handleMacos(trial_days_left=30, debug_mode=False):
print("OS : macOS")
print("Debug Mode: " + str(debug_mode))
def dump_debug(start_func, end_func, content_func, new_func):
print("function start line: {}".format(start_func))
print("function end line: {}".format(end_func))
print("function content:")
print(content_func)
print("new function content:")
print(new_func)
editor_macos = "/Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js"
editor_macos_test = r"C:\Users\housi\Desktop\Balsamiq\editor-macos-test.js"
if debug_mode:
editor_macos = editor_macos_test
print(editor_macos)
if not os.path.exists(editor_macos):
print("editor-macos.js NOT FOUND!")
exit(0)
get_trial_days_left_pattern = re.compile(r"\s*function\s+getTrialDaysLeftFromNativeData\(\w+\)\s*{")
func_start_line = -1
func_end_line = -1
found_a_match = False
function_content = ""
with open(editor_macos, encoding="utf8") as reader:
line_number = 0
# it starts at 1 because w have already matched one '{'
curly_braces_balance = 1
for line in reader.readlines():
line_number += 1
if not found_a_match:
match = get_trial_days_left_pattern.match(line)
if match is not None:
found_a_match = True
func_start_line = line_number
# TODO what if the start line is also the end line, One-Liner function
else:
curly_braces_balance += line.count("{")
curly_braces_balance -= line.count("}")
if curly_braces_balance == 0:
function_content = function_content + line
func_end_line = line_number
break
if func_start_line != -1:
function_content = function_content + line
body = "return {};".format(trial_days_left)
new_function_signature = "\nfunction getTrialDaysLeftFromNativeData(nativeData) {\n\t" + body + "\n}\n\n"
if debug_mode:
dump_debug(func_start_line, func_end_line, function_content, new_function_signature)
with open(editor_macos, encoding="utf8") as reader:
lines = reader.readlines()
# The first -1 to make it base 0 and the second one refers to the previous index
index = (func_start_line - 1) - 1
leading_count = 0
# Removing leading blank lines before the function definition
while not lines[index].strip():
lines.pop(index)
index -= 1
leading_count += 1
# The start and end indexes will change after removing the leading blank lines
func_start_line -= leading_count
func_end_line -= leading_count
# Removing trailing blank lines after the function end
index = func_end_line
while not lines[index].strip():
lines.pop(index)
# Removing the old function
for i in range(func_end_line - func_start_line + 1):
lines.pop(func_start_line - 1)
# Replacing it with the new function
lines.insert(func_start_line - 1, new_function_signature)
# Writing changes back to file
with open(editor_macos, "w", encoding="utf8") as f:
lines = "".join(lines)
f.write(lines)
print("IMPORTANT! please make sure to close Balsamiq before proceeding or the script won't have any effect")
years = int(input("How many years of trial do you want :) "))
if sys.platform.startswith("win"):
handleWindows(years * 365 * 24 * 60 * 60)
elif sys.platform.startswith("darwin"):
handleMacos(years * 365)
else:
print("Sorry, operating system not supported")
exit(0)
print("****************************************************************")
print("* Congratulations! You gained {} days of trial".format(years * 365))
print("* Please don't forget to leave a star ✭")
print("****************************************************************")
print("https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28")
webbrowser.open("https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28")
input("Press ENTER to exit")
@fokklz
Copy link

fokklz commented Nov 22, 2023

Thank you bro

@RobinRuf
Copy link

Godlike - Thanks!

@mahgoe
Copy link

mahgoe commented Nov 22, 2023

Thank you for your effort Houssem

@darioesposito
Copy link

Hi,

i have this error:

IMPORTANT! please make sure to close Balsamiq before proceeding or the script won't have any effect
How many years of trial do you want :) 1
OS : macOS
Debug Mode: False
/Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js
Traceback (most recent call last):
File "/Users/darioesposito/Downloads/c09e55e0e5f451aa10f8621a6680ba28-b16f52b9481a49c58f23aaf2b1ae9ca2e897c5d2/BalsamiqForever.py", line 115, in
handleMacos(years * 365)
File "/Users/darioesposito/Downloads/c09e55e0e5f451aa10f8621a6680ba28-b16f52b9481a49c58f23aaf2b1ae9ca2e897c5d2/BalsamiqForever.py", line 82, in handleMacos
while not lines[index].strip():

IndexError: list index out of range

can someone help? thanks

@HoussemNasri
Copy link
Author

@darioesposito The script works only on Windows, for MacOS follow the manual editing section.

@darioesposito
Copy link

Thank you @HoussemNasri but if i modify Editor-macos.js and then save try to open balsamiq it's says to me the software is broken. Any help? thank you

@HoussemNasri
Copy link
Author

HoussemNasri commented Nov 22, 2023

Hmmm, there is a chance that manual editing doesn't work anymore on recent versions of Blasamiq, I don't have a Mac to confirm. This comment appears to have found an alternative solution.

@darioesposito
Copy link

Thank you!

@ahmadtc
Copy link

ahmadtc commented Jan 31, 2024

Hi, I have figured out how to increase trial time manually on MacOS after none of these steps worked for me. (Tested on version 4.7.4)

Here's how I got it to work:

  1. Open this file in your text editor /Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js.

  2. Search for this function function getLicenseValidFromLicenseData(data).

  3. Replace function body by return true.

  4. Under that function, look for function called function getTrialDaysLeftFromNativeData(nativeData).

  5. Go to the statement let trialDaysLeft = Math.ceil(msecUntilExpiry / (1000 * 3600 * 24)); // to secs-hours-days.

  6. Replace 1000 with 10.

  7. Save File.

  8. Restart Balsamiq.

Screenshot 2024-01-31 at 1 59 29 PM

@wingsryder
Copy link

@ahmadtc
bal
This doesn't work for me, Even if this is showing big number of days, but when you check it via "About Balsm...." you can see still exact correct day. Check what showing to me

@Issam2204
Copy link

Hi, I have figured out how to increase trial time manually on MacOS after none of these steps worked for me. (Tested on version 4.7.4)

Here's how I got it to work:

  1. Open this file in your text editor /Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js.
  2. Search for this function function getLicenseValidFromLicenseData(data).
  3. Replace function body by return true.
  4. Under that function, look for function called function getTrialDaysLeftFromNativeData(nativeData).
  5. Go to the statement let trialDaysLeft = Math.ceil(msecUntilExpiry / (1000 * 3600 * 24)); // to secs-hours-days.
  6. Replace 1000 with 10.
  7. Save File.
  8. Restart Balsamiq.

Screenshot 2024-01-31 at 1 59 29 PM

Thanks a lot! This worked for me :)

@rs8dms
Copy link

rs8dms commented Apr 8, 2024

gracias papu!

@HobNoxious
Copy link

Thank you! I manually updated the JSON file on Windows, using a new value returned by epochconverter.com.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment